更改ViewModel的视图

我正在尝试为mt WPF应用程序实现MVVM设计模式。 为了将视图连接到视图模型,我使用ResourceDictionary (在Application.Resources ),看起来像

    

然后将视图模型简单地放入内容演示者中以显示它们。

现在,当用户按下按钮时,我想使用不同的视图显示SampleViewModel 。 如何更改SampleViewModel使用的数据模板?

少说更多的代码。 就你所说,你有SampleViewModel类。 我添加了Title属性演示和ViewType以识别正确的视图:

 public enum ItemViewType { View1, View2 }; public class SampleViewModel { public string Title { get; set; } public ItemViewType ViewType { get; set; } } 

用于两个视图的DataTemplateSelector ,具体取决于ViewType属性:

 class ItemViewTemplateSelector : DataTemplateSelector { public DataTemplate View1Template { get; set; } public DataTemplate View2Template { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { var vm = item as SampleViewModel; if (vm == null) return null; switch (vm.ViewType) { case ItemViewType.View1: return View1Template; case ItemViewType.View2: return View2Template; } return null; } } 

Xaml代码:

                 

主要部分是在MainViewModel类中,我在其中放置了切换视图的逻辑:

 public class MainViewModel : ViewModelBase { public MainViewModel() { this.ItemViewModel = new SampleViewModel { Title = "Some title", ViewType = ItemViewType.View1 }; this.SwitchViewCommand = new RelayCommand(() => { this.ItemViewModel.ViewType = this.ItemViewModel.ViewType == ItemViewType.View1 ? ItemViewType.View2 : ItemViewType.View1; //The magic senquence of actions which forces a contentcontrol to change the content template var copy = this.ItemViewModel; this.ItemViewModel = null; this.ItemViewModel = copy; }); } public RelayCommand SwitchViewCommand { get; set; } private SampleViewModel itemViewModel; public SampleViewModel ItemViewModel { get { return itemViewModel; } set { itemViewModel = value; RaisePropertyChanged("ItemViewModel"); } } } 

SwitchViewCommand可以是任何类型的命令,我使用mvvmlight库中的命令。

在命令的处理程序内部,我更改了viewmodel的类型并以一种棘手的方式更新属性ItemViewModel ,因为ContentControl仅在更改Content属性时刷新视图,并且除非您设置对不同对象的引用,否则不会更改此属性。

我的意思是,即使代码this.ItemViewModel = this.itemViewModel也不会改变视图。 这很奇怪,但解决方法并不需要太多工作。

您可以通过多种不同方式实现此目标,具体取决于您想要的架构。

  • 您可以编写自定义DataTemplateSelector并在ContentControl.ContentTemplateSelector上使用它并适当地选择这两个模板
  • 如果这种改变视图的模式发生在许多不同的地方和更频繁的UX,我还建议使用基于SampleViewModel中的属性的DataTemplate.DataTrigger切换这两个视图[我猜你可能在ViewModel中有一个区别属性知道那个州]

您可以通过在树中放置较低的类似资源来覆盖映射。 由于WPF将通过向上搜索来解析资源,因此这种覆盖将替换您现有的映射。