Использование вида master-detail с деталями разных типов

Я пытаюсь создать представление, которое будет отображать древовидное представление с одной стороны (мастер), а для выбранного узла - некоторую информацию слева (подробно) с использованием шаблона MVVM.

Древовидное представление связано с коллекцией ViewModel, которая на самом деле является абстрактным классом. У меня есть два класса, которые наследуют от моего абстрактного ViewModel, один представляет категорию, а другой требование.

В дереве категории могут иметь дочерние элементы, которые являются либо категориями, либо требованиями.

У требований не может быть детей, они просто листья.

то есть:

  • категория 1
    • требование 1
    • подкатегория 1
  • категория 2
    • подкатегория 2
  • категория 3

Мне удалось отобразить некоторые данные из абстрактного класса в моем подробном представлении. Моя проблема в том, что мне нужно отображать разные данные, если выбрана категория или требование... Я понятия не имею, как это сделать.

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

Мой XAML сейчас выглядит так:

<Grid DataContext="{Binding Requirements}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="350" />
        <ColumnDefinition Width="400*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
    </Grid.RowDefinitions>

    <TreeView 
        x:Name="treeRequirements"
        Grid.Column="0" Grid.Row="0" 
        HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
        ItemsSource="{Binding}">
        <TreeView.ItemContainerStyle>
            <!-- This Style binds a TreeViewItem to a PersonViewModel. -->
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                <Setter Property="FontWeight" Value="Normal" />
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="FontWeight" Value="Bold" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TreeView.ItemContainerStyle>

        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

    <Grid 
        Grid.Column="1" Grid.Row="0"
        DataContext="{Binding ElementName=treeRequirements, Path=SelectedItem}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>

        <!-- Name comes from the abstract class, so no problem -->
        <TextBlock 
            Grid.Row="0" Grid.Column="0">
            Name
        </TextBlock>
        <TextBox
            Grid.Row="0" Grid.Column="1" 
            Text="{Binding Path=Name, Mode=TwoWay}" />


    </Grid>
</Grid>

Моя проблема в том, что я понятия не имею, как отобразить различные детали в зависимости от типа модели представления, представленной выбранным узлом. Я могу отображать только свойства абстрактного класса.

Любая помощь?

РЕДАКТИРОВАТЬ

Подводя итог моему вопросу, вся основная деталь и древовидная структура не имеют никакого отношения к проблеме, ее просто нужно поместить в контекст. Моя проблема на самом деле просто отображать различные поля в зависимости от подтипа моей модели представления, которые могут различаться.

2 ответа

Решение

Мне был любопытен ваш вопрос, поэтому я немного огляделся вокруг. Похоже, вы можете использовать DataTemplateSelector. Здесь показан хороший пример.

Вам нужно объявить несколько HierarchicalDataTemplates как ресурсы, определяющие DataType атрибут для каждого. Если вы не укажете Treeview.ItemTemplate.net выберет лучший подходящий шаблон во время выполнения и отобразит данные соответственно.

Пример:

<TreeView ItemsSource={Binding}>
   <TreeView.Resources>
      <HierarchicalDataTemplate DataType="{x:Type local:Type1}">
      ...
      </HierarchicalDataTemplate>
      <HierarchicalDataTemplate DataType="{x:Type local:Type2}">
      ...
      </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

Вы также можете прочитать следующую статью (в частности, пример футбола, который использует HierarchicalDataTemplate: http://msdn.microsoft.com/en-us/library/ms742521.aspx

Другие вопросы по тегам