1

基本上,我有以下情况:

ViewModel: FooViewModel : BaseViewModel, BarViewModel : BaseViewModel
Views: MainView, FooView,BarView

现在我“注入”视图并设置DataContext使用DataTemplateand DataTemplateSelector。显然, myItemsControl ItemSource绑定到 a ObservableCollection<BaseViewModel>,其中它包含(目前) aFooViewModel和 a的实例BarViewModel

问题是我想介绍一个AlternateFooView我想使用的FooViewModel. 我想我会创建另一个DataTemplateDataTemplateSelector返回它,但需要有特殊的逻辑来确定要返回哪个 DataTemplate(我不能只通过哪个 ViewModel 在那里),这意味着我必须有一些BaseViewModel 中的属性或字段的类型。我不知道这是否真的是一个好主意,因为这似乎将一个字段/属性引入到仅用于选择视图的 ViewModel 中。它不会伤害我的单元测试,但包含一个字段只是为了帮助决定选择哪个 UI 视图似乎是一种浪费。我认为它不会破坏 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} />


谢谢!

4

1 回答 1

4

I agree with krishnaaditya that the question really boils down to what determines which View to use based on the state of the ViewModel. This type of logic is often placed into a template selector, which works great. If you don't want to put that logic into the template selector, consider externalizing it by using my Routed Template Selection approach. That makes it easy to delegate the template selection logic by using a routed event.

The idea you proposed in your comment about using a DataTrigger could also work, but that reintroduces the need for a property on the VM object that indicates which View to load (which you said you don't want). In my opinion, that's not necessarily a bad thing.

于 2011-04-14T18:40:31.760 回答