2011-02-01 53 views
0

我有一个需要显示某些节点​​的WPF树。假设我有两种实体,EntityA和EntityB。这两个实体都实现了一个通用接口IEntity。现在,EntityA将拥有EntityB元素和EntityA元素的集合。我怎样才能通过HierarchicalDataTemplate显示这个?关于WPF树中分层数据模板的问题

我在我的虚拟机中公开了一个名为“DisplayItems”的ObservableCollection(),它将包含EntityA类型的元素。

EnittyA和EntityB都会有另一个名为“ItemCollection”的ObservableCollection。对于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代码没有得到正确粘贴 – 2011-02-01 04:48:08

回答

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>