更改 ViewModel 的视图 [英] Changing the View for a ViewModel
问题描述
我正在尝试为 mt WPF 应用程序实现 MVVM 设计模式.为了将视图连接到视图模型,我使用了一个 ResourceDictionary
(在 Application.Resources
中使用),看起来像
I am trying to implement the MVVM design patern for mt WPF application. In order to connect the view to the viewmodels, I use a ResourceDictionary
(used in Application.Resources
), that looks like
<DataTemplate DataType={x:Type viewmodel:SampleViewModel}>
<view:SampleView1 />
</DataTemplate>
然后将视图模型简单地放入内容展示器中以显示它们.
The view models are then simply put into content presenters to display them.
现在,当用户按下按钮时,我想使用不同的视图显示 SampleViewModel
.如何更改用于 SampleViewModel
的数据模板?
Now, when the user presses a button, I'd like to display SampleViewModel
using a different view. How do I change the data template used for SampleViewModel
?
推荐答案
少言多码.正如您所说,您拥有 SampleViewModel
类.我添加了用于演示的属性 Title
和用于识别正确视图的 ViewType
:
Less words more code.
As far as you said, you have the class SampleViewModel
. I added the property Title
for demonstration and ViewType
for identifying the correct view:
public enum ItemViewType { View1, View2 };
public class SampleViewModel
{
public string Title { get; set; }
public ItemViewType ViewType { get; set; }
}
两个视图的 DataTemplateSelector
取决于 ViewType
属性:
The DataTemplateSelector
for two views depending on the ViewType
property:
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;
}
}
Xml 代码:
<Window.Resources>
<DataTemplate x:Key="view1Template">
<TextBlock Text="{Binding Title}" Foreground="Red"/>
</DataTemplate>
<DataTemplate x:Key="view2Template">
<TextBox Text="{Binding Title}" />
</DataTemplate>
<local:ItemViewTemplateSelector x:Key="viewTemplateSelector"
View1Template="{StaticResource view1Template}"
View2Template="{StaticResource view2Template}"/>
</Window.Resources>
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<StackPanel>
<Button Content="ChangeView" HorizontalAlignment="Center" Command="{Binding SwitchViewCommand}"/>
<ContentControl Content="{Binding ItemViewModel}" ContentTemplateSelector="{StaticResource viewTemplateSelector}"/>
</StackPanel>
主要部分在 MainViewModel
类中,我在其中放置了切换视图的逻辑:
The main part is in the class MainViewModel
where I've put the logic for switching views:
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 库中的命令.
The SwitchViewCommand
can be any type of command, I use the command from the mvvmlight library.
在命令的处理程序中,我以一种棘手的方式更改了视图模型的类型并更新了属性 ItemViewModel
,因为 ContentControl
仅在更改内容时刷新视图属性,除非您设置对不同对象的引用,否则该属性不会更改.
Inside the handler of the command I change the type of viewmodel and update the property ItemViewModel
in a tricky way because a ContentControl
refreshes a view only if to change the Content property, and this property will not be changed unless you set a reference to different object.
我的意思是,即使代码 this.ItemViewModel = this.itemViewModel
也不会改变视图.这很奇怪,但解决方法不需要太多工作.
I mean, even the code this.ItemViewModel = this.itemViewModel
will not change the view.
It's strange, but the workaround doesn't require much work.
这篇关于更改 ViewModel 的视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!