WPF TreeView如何同时显示多类型节点及Element关联的Value?
解决方案
要让TreeView中Element节点同时展示SubElements和Values,核心是把这两个集合合并后作为HierarchicalDataTemplate的ItemsSource,以下提供两种可行实现方式:
方式一:在Element类中新增合并属性(推荐,代码更简洁)
直接在Element类里添加一个只读属性,合并SubElements和Values:
public class Element { public string Name { get; set; } public IList<Element> SubElements { get; set; } = new List<Element>(); public IList<Value> Values { get; set; } = new List<Value>(); // 合并子元素和值项,顺序可按需调整 public IEnumerable<object> CombinedChildren { get { foreach (var subElement in SubElements) yield return subElement; foreach (var value in Values) yield return value; } } }
然后修改XAML中HierarchicalDataTemplate的ItemsSource绑定:
<TreeView x:Name="TreeView" Grid.Row="0" ItemsSource="{Binding TreeViewElements, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}"> <TreeView.Resources> <HierarchicalDataTemplate DataType="{x:Type local:Element}" ItemsSource="{Binding CombinedChildren}"> <TextBlock Text="{Binding Name}"/> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type local:Value}"> <TextBlock Text="{Binding Name}"/> </DataTemplate> </TreeView.Resources> </TreeView>
方式二:使用MultiBinding+转换器(不修改模型类)
如果无法修改Element类,可以通过WPF的转换器合并两个集合:
1. 创建集合合并转换器
public class CombineCollectionsConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { var combinedList = new List<object>(); foreach (var collection in values) { if (collection is IEnumerable enumerable) { foreach (var item in enumerable) { combinedList.Add(item); } } } return combinedList; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
2. 修改XAML配置
在TreeView资源中声明转换器,并通过MultiBinding绑定SubElements和Values:
<TreeView x:Name="TreeView" Grid.Row="0" ItemsSource="{Binding TreeViewElements, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}"> <TreeView.Resources> <local:CombineCollectionsConverter x:Key="CombineCollectionsConverter"/> <HierarchicalDataTemplate DataType="{x:Type local:Element}"> <HierarchicalDataTemplate.ItemsSource> <MultiBinding Converter="{StaticResource CombineCollectionsConverter}"> <Binding Path="SubElements"/> <Binding Path="Values"/> </MultiBinding> </HierarchicalDataTemplate.ItemsSource> <TextBlock Text="{Binding Name}"/> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type local:Value}"> <TextBlock Text="{Binding Name}"/> </DataTemplate> </TreeView.Resources> </TreeView>
内容的提问来源于stack exchange,提问作者Floriant Fekete
相关产品推荐
相关产品推荐

