2011-02-01 5 views
0

У меня есть дерево WPF, которому нужно показать некоторые узлы. Допустим, у меня есть 2 типа сущностей, EntityA и EntityB. Оба этих объекта реализуют общий интерфейс IEntity. Теперь EntityA будет иметь набор элементов EntityB, а также элементы EntityA. Как я могу показать это через HierarchicalDataTemplate?Вопрос о шаблоне данных иерархии в дереве WPF

Я показываю ObservableCollection(), называемый «DisplayItems» в моей виртуальной машине, который будет содержать элементы типа EntityA.

И у EnittyA, и у EntityB будет еще один ObservableCollection, называемый «ItemCollection». Для EntityA список ItemCollection должен идеально содержать объекты EntityA и EntityB.

Ток HierarchicalDataTemplate и XAML, который я использую выглядит следующим образом:

<HierarchicalDataTemplate ItemsSource="{Binding Path=ItemCollection}" DataType="{x:Type Entities:EntityB}"> 
     <Grid> 
     <StackPanel Orientation="Horizontal" x:Name="compositeCT"> 
      <Image Source="/Images/EntityB.png" Width="15" Height="15"/> 
      <Label Foreground="Blue" Content="{Binding Path=Name}"/> 
      <Label Foreground="Black" Content=" = "/> 
      <Label Foreground="Blue" Content="{Binding Path=CompositeLabel}"/> 
     </StackPanel> 
     <StackPanel Orientation="Horizontal" x:Name="nCompositeCT"> 
      <Image Source="/Images/EntityB.png" Width="15" Height="15"/> 
      <TextBlock Foreground="Blue" Text="{Binding Path=Name}"/> 
     </StackPanel> 
<HierarchicalDataTemplate.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Foreground="Green" Text="{Binding}"/> 
     </DataTemplate> 
</HierarchicalDataTemplate.ItemTemplate> 
</HierarchicalDataTemplate> 

<HierarchicalDataTemplate ItemsSource="{Binding Path=ItemCollection}" DataType="{x:Type Entities:EntityA}"> 
     <StackPanel Orientation="Horizontal" > 
     <Image Source="/Images/ElementA.png" Margin="3" Width="15" Height="15" Focusable="False"/> 
     <TextBlock Foreground="Red" Text="{Binding Path = Name}" Focusable="False"/> 
     </StackPanel> 
    </HierarchicalDataTemplate> 

<TreeView x:Name="tvMyTree" 
      ItemsSource="{Binding DisplayItems}" 
      AllowDrop="True"   
      VirtualizingStackPanel.IsVirtualizing="True" 
      VirtualizingStackPanel.VirtualizationMode="Recycling" 
      ScrollViewer.IsDeferredScrollingEnabled="True" 
      Margin="5" 
      TreeViewItem.Expanded="OnTreeViewItemExpanded" 
      TreeViewItem.Selected="OnTreeViewItemSelected" 
     /> 
+0

Похоже, ваш XAML код не получили вставил правильно –

ответ

0

Вы можете определить два HierarchicalDataTemplates вы прекрасны. И вместо TextBlock вы можете поставить любую сложную визуализацию вам нужно в зависимости от других свойств вашего EntityA и EntityB

 <HierarchicalDataTemplate DataType="{x:Type local:EnittyA}" ItemsSource="{Binding ItemCollection}" > 
      <TextBlock Text="{Binding Name}"/> 
     </HierarchicalDataTemplate> 
     <HierarchicalDataTemplate DataType="{x:Type local:EnittyB}" ItemsSource="{Binding ItemCollection}" > 
      <TextBlock Text="{Binding Name}"/> 
     </HierarchicalDataTemplate> 
0

Я полагаю, ItemTemplateSelector подходит идеально подходит к вашим требованиям. ItemTemplateSelector наследуется, поэтому вы не должны заботиться о приемнике конечных точек шаблона. Приемник (пункт контейнер) просто обращается к селектору и последний возвращает правильный шаблон в соответствии с ТипДанным:

public class LayoutItemTemplateSelectorItem 
{ 
    public Type TargetType 
    { 
     get; 
     set; 
    } 
    public DataTemplate Template 
    { 
     get; 
     set; 
    } 
} 
[ContentProperty("Items")] 
public class LayoutItemTemplateSelector : DataTemplateSelector 
{ 
    public LayoutItemTemplateSelector() 
    { 
     this.Items = new Collection<LayoutItemTemplateSelectorItem>(); 
    } 
    public Collection<LayoutItemTemplateSelectorItem> Items 
    { 
     get; 
     private set; 
    } 
    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     var component = (LayoutItem)item; 
     var typeToSearch = component.GetType(); 

     var foundItem = this.Items 
      .Where(i => i.TargetType == typeToSearch) 
      .FirstOrDefault(); 

     if (foundItem != null) 
     { 
      return foundItem.Template; 
     } 

     throw new Exception(string.Format(Properties.Resources.AppropriateTemplateNotFound, typeToSearch.FullName)); 
    } 
} 

Использования в XAML:

<UserControl ...> 
    <UserControl.Resources> 
     <ResourceDictionary> 

      <HierarchicalDataTemplate x:Key="EntityBTemplate" 
             ItemsSource="{Binding Path=ItemCollection}" 
             DataType="{x:Type Entities:EntityB}"> 
       ... 
      </HierarchicalDataTemplate> 

      <HierarchicalDataTemplate x:Key="EntityATemplate" 
             ItemsSource="{Binding Path=ItemCollection}" 
             DataType="{x:Type Entities:EntityA}"> 
       ... 
      </HierarchicalDataTemplate> 

      <LayoutItemTemplateSelector x:Key="TemplateSelector"> 
       <LayoutItemTemplateSelectorItem TargetType="{x:Type EntityA}" 
               Template="{StaticResource EntityATemplate}"/> 
       <LayoutItemTemplateSelectorItem TargetType="{x:Type EntityB}" 
               Template="{StaticResource EntityBTemplate}"/> 
      </LayoutItemTemplateSelector> 
     </ResourceDictionary> 
    </UserControl.Resources> 
<Grid> 
    <TreeView ItemsSource="{Binding DisplayItems}" 
       ItemTemplateSelector="{StaticResource TemplateSelector}"/> 
</Grid> 
</UserControl> 
Смежные вопросы