WPF: переключение UserControls в зависимости от соответствующих ViewModels (MVVM) - PullRequest
20 голосов
/ 16 февраля 2011

Я попытаюсь упростить задачу, над которой я работаю, представив этот пример:

Предположим, что у нас есть следующая иерархия классов моделей:

Animal
   Lion
   Snake
   Bird

... соответствующие ViewModels:

AnimalCollectionViewModel
   AnimalViewModel
      LionViewModel
      SnakeViewModel
      BirdViewModel

... и соответствующие виды:

AnimalCollectionView
   LionView
   SnakeView
   BirdView

Предполагается, что AnimalCollection содержит список, заполненный объектами разных типов животных, а под списком имеется сетка свойств для установки свойств выбранного животного. Очевидно, что сетки свойств будут иметь разные свойства и должны изменяться при изменении типа выбранного элемента.

Вопрос: как реализовать переключение сеток свойств в WPF по шаблону MVVM? Используя какой механизм?

В настоящее время у меня есть абстрактное свойство enum в базовом ViewModel (AnimalViewModel.PropertyGridType = {Lion, Snake, Bird}), которое производные классы реализуют, возвращая соответствующие значения. А AnimalCollectionView изменяет пользовательские элементы управления сеткой свойств в зависимости от значения этого свойства. Примерно так:

...

<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}" />

...

Но я не уверен, что это правильный подход. (По крайней мере, мне не нравится вводить вспомогательное свойство enum. Можно ли вывести необходимый пользовательский элемент управления на основе типа ViewModel?) Кто-нибудь может посоветовать другие варианты? Заранее спасибо!

Ответы [ 2 ]

22 голосов
/ 16 февраля 2011

Можно ли вывести необходимый пользовательский элемент управления на основе типа ViewModel?

Ты имеешь в виду, как это?

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

См. «Применение представления к модели представления» в Статья Джоша Смита о MVVM .

Изменить:

Вот тривиальный пример выбора шаблона на основе типов, который вы можете вставить в Kaxaml, чтобы доказать себе, что он действительно работает:

<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>
2 голосов
/ 16 февраля 2011

Для этого вы можете использовать DataTemplateSelector . Выбор правильного шаблона зависит от вас. Вы можете использовать enums или test для типа класса, если хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...