我对 WPF 和 MVVM 比较陌生,我发现的最难的事情是如何简单地切换应用程序中的用户控件或 View 。
在 winforms 中,要删除控件本身,您可以简单地说 this.Parent.Controls.Remove(this);
在 WPF 中没有通用的父控件,您必须将其类型转换为特定类型(即网格),然后将其删除。
这似乎也打破了 MVVM 架构。我还尝试了数据模板和内容展示器,它们运行良好,但我无法从代码更改数据上下文,因为数据上下文始终是 View 模型定位器。
现在在 WPF 中页面是可以接受的方式吗?如果我有一个带有自定义 usecontrol 的网格并且我想根据 viewModel 中的某个变量来切换它怎么办?在 WPF 中似乎无法轻松完成最简单的任务。
最佳答案
你会在你的父 ViewModel 中这样做。
例如,如果您的页面(称为 PageViewModel
)有两个 View ( ViewModelA
和 ViewModelB
),您将在 PageViewModel
上拥有一个属性叫 CurrentView
,这将决定哪个 View 是可见的。当PageViewModel.CurrentView
设置为 ViewModelA
的实例,然后使用ViewA的DataTemplate来绘制内容。当它设置为 ViewModelB
的实例时,ViewB的DataTemplate就显示出来了。
<DataTemplate DataType="{x:Type local:PageViewModel}">
<ContentControl Content="{Binding CurrentView}" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelA}">
<TextBlock Text="I'm ViewModelA" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelB}">
<TextBlock Text="I'm ViewModelB" />
</DataTemplate>
从父 View (在本例中为
PageViewModel
的 DataTemplate)调用切换 View 命令是理想的,但是如果您想从 ViewModelA/B 中切换 View ,您可以手动连接事件,当对象被创建( CurrentView.ChangeViewCommand = this.ChangeViewCommand
)或查看消息系统。 MVVM Light 有一个简单的 Messenger
我发现这个类相当容易使用,或者 Prism 有一个更高级的 EventAggregator
如果您想为同一个 ViewModel 切换 View ,我建议使用 Mode 属性来确定要使用的 View 。例如:
<DataTemplate x:Key="ViewA" DataType="{x:Type local:MyViewModel}">
<TextBlock Text="I'm ViewModelA" />
</DataTemplate>
<DataTemplate x:Key="ViewB" DataType="{x:Type local:MyViewModel}">
<TextBlock Text="I'm ViewModelB" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:MyViewModel}">
<ContentControl Content="{Binding }">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource ViewA}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Mode}" Value="2">
<Setter Property="ContentTemplate" Value="{StaticResource ViewB}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
编辑
我其实看到很多这样的问题,所以发了一些关于它的东西here如果有人感兴趣
关于wpf - 在 MVVM-light 和 WPF 中切换 View /用户控件的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6114479/