基本上,我有以下情况:
查看型号:FooViewModel : BaseViewModel
, BarViewModel : BaseViewModel
浏览量:MainView
, FooView
, BarView
现在我“注入(inject)” View 并设置 DataContext
使用 DataTemplate
和 DataTemplateSelector
.显然,我的 ItemsControl
ItemSource
绑定(bind)到 ObservableCollection<BaseViewModel>
其中它包含(目前)FooViewModel
的一个实例和 BarViewModel
问题是我想介绍一个AlternateFooView
我想使用相同的FooViewModel
.我想我会创建另一个 DataTemplate
并拥有我的DataTemplateSelector
返回它,但需要有特殊的逻辑来确定要返回哪个 DataTemplate(我不能只通过那里的哪个 ViewModel),这意味着我必须在 BaseViewModel 中有某种类型的属性或字段。我不知道这是否真的是一个好主意,因为这似乎将一个字段/属性引入到仅用于选择 View 的 ViewModel 中。它不会伤害我的单元测试,但包含一个字段只是为了帮助决定选择哪个 UI View 似乎是一种浪费。我认为它不会破坏 MVVM,但我很好奇是否有人有其他更好的想法?我更不喜欢的替代想法......
想法2:
- 将 FooViewModel 转换为 2 个不同 FooViewModel 扩展的基类(即 BaseFooViewModel、FooViewModel、DifferentialFooViewModel)。这似乎很愚蠢,因为 FooViewModel 和 DifferentFooViewModel 除了它们的类类型之外真的没有任何区别。
想法3:
- 只需复制 FooViewModel 并将其设为 FooViewModel2(它将与 FooViewModel 完全相同)。这似乎比想法 2 还要糟糕。
示例代码(明显调整):
public abstract class BaseViewModel : NotificationObject
{
//Common Stuff
}
public abstract MainViewModel : NotificationObject
{
public MainViewModel()
{
MyItems = new ObservableCollection<BaseViewModel>()
{
new FooViewModel();
new BarViewModel();
new FooViewModel(); //New Item -- I want it to use the DifferentFooView
}
//Load items from a DAL later
}
public ObservableCollection<BaseViewModel> MyItems { get; set; }
//Other Stuff
}
<l:MyItemsControl ItemSource={Binding MyItems} ContentTemplateSelector={StaticResource MyTemplateSelector} />
谢谢!
最佳答案
我同意 krishnaaditya 的观点,这个问题实际上归结为是什么决定了根据 ViewModel 的状态使用哪个 View。这种类型的逻辑通常放置在模板选择器中,效果很好。如果您不想将该逻辑放入模板选择器中,请考虑使用我的 Routed Template Selection 将其外部化。方法。这使得通过使用路由事件来委派模板选择逻辑变得容易。
您在评论中提出的关于使用 DataTrigger 的想法也可以工作,但这重新引入了对 VM 对象上的属性的需求,该属性指示要加载的 View (您说您不想要)。在我看来,这不一定是坏事。
关于WPF DataTemplate/DataTemplateSelector -- 2 个不同 View 使用的 ViewModel 的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5667522/