在MVVM-light和WPF中切换视图/用户控件的最佳方法是什么?

JRe*_*eed 24 wpf mvvm-light

我对WPF和MVVM比较陌生,我发现最困难的事情就是如何简单地在应用程序中切换用户控件或视图.

在winforms中,要让控件自行删除,你可以简单地说这个.Parent.Controls.Remove(this);

在WPF中没有通用的Parent控件,您必须将其类型转换为特定类型(即Grid),然后将其删除.

这似乎也打破了MVVM架构.我还尝试了数据模板和内容演示器,除了我无法从代码更改datacontext这一事实外,它工作得很好,因为datacontext始终是viewmodellocator.

现在,页面是否可以在WPF中执行此操作?如果我有一个带有自定义usecontrol的网格并且我想根据viewModel中的某个变量切换它会怎么样?似乎在WPF中无法轻松完成最简单的任务.

Rac*_*hel 38

您可以在父ViewModel中执行此操作.

例如,如果您的页面(调用它PageViewModel)有两个视图(ViewModelAViewModelB),您将PageViewModel调用一个属性CurrentView,这将确定哪个视图可见.当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>
Run Code Online (Sandbox Code Playgroud)

从父视图调用switch views命令是理想的(在本例中是DataTemplate PageViewModel),但是如果你想从ViewModelA/B中切换视图,你可以在创建对象时手动挂钩事件(CurrentView.ChangeViewCommand = this.ChangeViewCommand)或查看消息传递系统.MVVM Light有一个简单的Messenger类,我发现它很容易使用,或者Prism有更高级的EventAggregator

如果要为同一ViewModel切换视图,我建议使用Mode属性来确定要使用的视图.例如:

<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>
Run Code Online (Sandbox Code Playgroud)

编辑

我实际上看到这样的问题出现了很多,所以如果有人有兴趣,可以在这里发布一些相关信息