WPF树中的层次数据模板问题
我有一个WPF树,它需要显示一些节点。假设我有两种类型的实体,EntityA和EntityB。这两个实体都实现了一个通用接口。现在,EntityA将拥有EntityB元素和EntityA元素的集合。如何通过HierarchycalDataTemplate显示此内容 我在VM中公开了一个名为“DisplayItems”的ObservableCollection(),它将包含EntityA类型的元素 EnittyA和EntityB都将有另一个称为“ItemCollection”的ObservableCollection。对于EntityA,ItemCollection列表理想情况下应该包含EntityA和EntityB类型的实体 我使用的当前HierarchycalDataTemplate和XAML如下所示:WPF树中的层次数据模板问题,wpf,Wpf,我有一个WPF树,它需要显示一些节点。假设我有两种类型的实体,EntityA和EntityB。这两个实体都实现了一个通用接口。现在,EntityA将拥有EntityB元素和EntityA元素的集合。如何通过HierarchycalDataTemplate显示此内容 我在VM中公开了一个名为“DisplayItems”的ObservableCollection(),它将包含EntityA类型的元素 EnittyA和EntityB都将有另一个称为“ItemCollection”的Observable
<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"
/>
您可以定义两个Hierarchy-CalDataTemplates,这很好。在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>
我认为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));
}
}
公共类LayoutItemTemplateSelectorItem
{
公共类型TargetType
{
收到
设置
}
公共数据模板
{
收到
设置
}
}
[内容属性(“项目”)]
公共类LayoutItemTemplateSelector:DataTemplateSelector
{
public LayoutItemTemplateSelector()
{
this.Items=新集合();
}
公众收集物品
{
收到
私人设置;
}
公共覆盖数据模板SelectTemplate(对象项,DependencyObject容器)
{
var组件=(LayoutItem)项;
var typeToSearch=component.GetType();
var foundItem=this.Items
.其中(i=>i.TargetType==typeToSearch)
.FirstOrDefault();
if(foundItem!=null)
{
返回foundItem.Template;
}
抛出新异常(string.Format(Properties.Resources.properteTemplateNotFound,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>
...
...
看起来您的xaml代码没有正确粘贴