2011-02-01 56 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>