本文介绍了WPF:根据相应的 ViewModels (MVVM) 切换 UserControls的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将尝试通过想象这个例子来简化我正在处理的任务:

I'll try to simplify the task I'm working on by imagining this example:

假设我们有以下模型类层次结构:

Let's suppose that we have the following hierarchy of model classes:

Animal
   Lion
   Snake
   Bird

...对应的视图模型:

...corresponding ViewModels:

AnimalCollectionViewModel
   AnimalViewModel
      LionViewModel
      SnakeViewModel
      BirdViewModel

... 和相应的视图:

... and corresponding views:

AnimalCollectionView
   LionView
   SnakeView
   BirdView

假设 AnimalCollection 包含一个充满不同类型动物对象的列表,在列表下方有一个属性网格,用于设置所选动物的属性.显然,属性网格将具有不同的属性,并且应该在所选项目的类型发生变化时发生变化.

It's supposed that AnimalCollection contains a list filled with objects of different types of animals and below the list it has a property grid for setting the properties of a selected animal. Obviously the property grids will have different properties and should change when the type of a selected item changes.

问题是:如何根据MVVM模式实现WPF中属性网格的切换?使用什么机制?

The question is: How to implement switching of the property grids in WPF according to the MVVM pattern? Using what mechanism?

目前我在基础 ViewModel (AnimalViewModel.PropertyGridType = {Lion, Snake, Bird}) 中有一个抽象枚举属性,派生类通过返回相应的值来实现它.并且 AnimalCollectionView 会根据此属性的值更改属性网格用户控件.像这样:

Currently I have an abstract enum property in the base ViewModel (AnimalViewModel.PropertyGridType = {Lion, Snake, Bird}) which the derived classes implement by returning corresponding values. And the AnimalCollectionView changes the property grid user controls depending on the value of this property. Something like this:

...

<UserControl.Resources>
    <Style x:Key="PropertyGridStyle" TargetType="ContentControl">
        <Style.Triggers>
            <DataTrigger Binding="{Binding PropertyGridType}" Value="Lion">
                <Setter Property="Content">
                    <Setter.Value>
                        <view:LionPropertyGridView />
                    </Setter.Value>
                </Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding PropertyGridType}" Value="Snake">
                <Setter Property="Content">
                    <Setter.Value>
                        <view:SnakePropertyGridView />
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

<ContentControl Style="{StaticResource PropertyGridStyle}" />

...

但我不确定这是否是正确的方法.(至少我不喜欢引入辅助枚举属性.是否可以根据 ViewModel 类型推导出必要的用户控件?)有人可以建议其他选择吗?提前致谢!

But I'm not sure whether it is the right approach. (At least I don't like introducing the auxiliary enum property. Is it possible to deduce the necessary user control based on a ViewModel type?)Can anybody advise other options?Thanks in advance!

推荐答案

你的意思是,像这样?

<Window.Resources>
   <DataTemplate DataType="{x:Type vm:LionViewModel}">
      <v:LionView />
   </DataTemplate>
   <DataTemplate DataType="{x:Type vm:SnakeViewModel}">
      <v:SnakeView />
   </DataTemplate>
   <DataTemplate DataType="{x:Type vm:BirdViewModel}">
      <v:BirdView/>
   </DataTemplate>
</Window.Resources>

参见将视图应用到视图模型";在 Josh Smith 关于 MVVM 的文章中.

See "Applying a View to a View Model" in Josh Smith's article on MVVM.

这是一个基于类型的模板选择的简单示例,您可以将其粘贴到 Kaxaml 中以向自己证明它确实有效:

Here's a trivial example of type-based template selection that you can paste into Kaxaml to prove to yourself that it really works:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <Page.Resources>
    <sys:String x:Key="string">this is a string</sys:String>
    <sys:Int32 x:Key="int32">1234</sys:Int32>
    <DataTemplate DataType="{x:Type sys:String}">
      <TextBlock Foreground="Red" Text="{Binding}"/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type sys:Int32}">
      <TextBlock Foreground="Blue" Text="{Binding}"/>
    </DataTemplate>
  </Page.Resources>
  <StackPanel>  
    <ContentControl Content="{Binding Source={StaticResource string}}"/>
    <ContentControl Content="{Binding Source={StaticResource int32}}"/>
  </StackPanel>
</Page>

这篇关于WPF:根据相应的 ViewModels (MVVM) 切换 UserControls的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 03:22