更改 ViewModel 的视图 [英] Changing the View for a ViewModel

查看:15
本文介绍了更改 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屋!

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