在MVVM-light和WPF中切换视图/用户控件的最佳方法是什么? [英] What is the best way to switch views/usercontrols in MVVM-light and WPF?

查看:466
本文介绍了在MVVM-light和WPF中切换视图/用户控件的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对WPF和MVVM相对较新,而我发现最难的是如何在应用程序中简单地切换用户控件或视图.

I'm relatively new to WPF and MVVM and the hardest thing I have found is how to simply switch a usercontrol or a view in an application.

在winforms中,要删除控件,您可以简单地说this.Parent.Controls.Remove(this);

In winforms, to have a control remove itself you would simple say this.Parent.Controls.Remove(this);

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

In WPF there is no generic Parent control, you would have to typecast it to the specific type (i.e. Grid) and then remove it.

这似乎也破坏了MVVM体系结构.我还尝试了数据模板和内容呈现器,它们很好用,但事实是我无法从代码中更改数据上下文,因为数据上下文始终是viewmodellocator.

This also seems to break the MVVM architecture. I have also tried data templates and content presenters, which work well, except for the fact that I can't change the datacontext from code, since the datacontext is always the viewmodellocator.

现在在WPF中是否可以使用页面来做到这一点?如果我有一个带有自定义usecontrol的网格,并且想基于viewModel中的某个变量进行切换,该怎么办?似乎最简单的任务无法在WPF中轻松完成.

Are pages the acceptable way to do this in WPF now? What if I had a grid with a custom usecontrol and I wanted to switch it based on some variable in the viewModel? It seems like the simplest tasks cannot be accomplished easily in WPF.

推荐答案

您可以在父级ViewModel中这样做.

You would do so in your parent ViewModel.

例如,如果您的页面(称为PageViewModel)具有两个视图(ViewModelAViewModelB),则您将在PageViewModel上拥有一个名为CurrentView的属性,这将确定哪个视图是可见的.当PageViewModel.CurrentView设置为ViewModelA的实例时,则使用ViewA的DataTemplate绘制内容.将其设置为ViewModelB的实例时,将显示ViewB的DataTemplate.

For example, if your page (call it PageViewModel) had two views (ViewModelA and ViewModelB), you would have a property on PageViewModel called CurrentView, and this would determine which View is visible. When PageViewModel.CurrentView is set to an instance of ViewModelA, then ViewA's DataTemplate is used to draw the content. When it's set to an instance of ViewModelB, ViewB's DataTemplate is displayed.

<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>

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

It would be ideal to call the switch views command from the parent view (in this case the DataTemplate for the PageViewModel), however if you wanted to switch views from within ViewModelA/B, you can either hook up the event manually when the objects get created (CurrentView.ChangeViewCommand = this.ChangeViewCommand) or look into a messaging system. MVVM Light has a simple Messenger class which I found was fairly easy to use, or Prism has a more advanced EventAggregator

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

If you want to switch Views for the same ViewModel, I would recommend a Mode property that gets used to determine which view to use. For example:

<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>

编辑

我实际上看到了这类问题,因此发布了一些有关它的信息

I actually see this kind of question come up a lot, so posted something about it here if anyone is interested

这篇关于在MVVM-light和WPF中切换视图/用户控件的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆