WPF中如何实现List<List<int>>的TreeView正确展示?
解决方案
首先修正EntityDisplayObject构造函数的语法错误(原代码字符串格式化缺少闭合大括号):
public sealed class EntityDisplayObject { public ICollection Collection { get; private set; } public string CollectionName { get; private set; } public EntityDisplayObject(ICollection collection) { this.Collection = collection; // 修复格式化字符串的语法错误 this.CollectionName = $"{this.Collection.GetType().Name}[{this.Collection.Count}]"; } }
核心修改:用TreeView层级模板替代嵌套ListBox
TreeView本身支持层级结构展示,无需嵌套ListBox。通过HierarchicalDataTemplate递归处理嵌套集合,具体XAML代码如下:
<!-- 先在根节点(如Window/UserControl)添加资源声明 --> <Window.Resources> <!-- 引入系统命名空间和本地项目命名空间 --> <xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:你的项目命名空间"/> <!-- 转换单个对象为集合的转换器(如果ViewModel只有单个EntityDisplayObject实例时用) --> <local:SingleItemToListConverter x:Key="SingleItemToListConverter"/> <!-- 生成集合显示名称的转换器 --> <local:CollectionNameConverter x:Key="CollectionNameConverter"/> <!-- 处理int类型项的模板 --> <DataTemplate DataType="{x:Type sys:Int32}"> <TextBlock Text="{Binding}"/> </DataTemplate> <!-- 处理ICollection类型项的递归模板 --> <HierarchicalDataTemplate DataType="{x:Type sys:ICollection}" ItemsSource="{Binding}"> <TextBlock Text="{Binding Converter={StaticResource CollectionNameConverter}}"/> </HierarchicalDataTemplate> <!-- 处理EntityDisplayObject的顶层模板 --> <HierarchicalDataTemplate DataType="{x:Type local:EntityDisplayObject}" ItemsSource="{Binding Collection}"> <TextBlock Text="{Binding CollectionName}"/> </HierarchicalDataTemplate> </Window.Resources> <!-- 修改后的TreeView布局 --> <Grid x:Uid="Grid_4"> <TreeView x:Uid="TreeView_2" Background="Transparent" BorderThickness="0" Padding="0" <!-- 绑定到ViewModel中的EntityDisplayObject集合;如果是单个实例,用转换器转成集合 --> ItemsSource="{Binding YourEntityDisplayObject, Converter={StaticResource SingleItemToListConverter}}"> </TreeView> </Grid>
补充转换器实现
需要添加两个辅助转换器类:
- 单个对象转集合的转换器:
public class SingleItemToListConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value == null ? new List<object>() : new List<object> { value }; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
- 生成集合显示名称的转换器:
public class CollectionNameConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is ICollection collection) { return $"{collection.GetType().Name}[{collection.Count}]"; } return value?.ToString() ?? string.Empty; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
效果说明
修改后TreeView会自动递归展示嵌套结构:
- 顶层显示
EntityDisplayObject的CollectionName - 展开后,若为
List<int>则直接显示每个数值;若为List<List<int>>,每个子项会显示类似List1[3]`的名称,展开后继续显示内部的int值
内容的提问来源于stack exchange,提问作者Arthur Rodrigues
相关产品推荐
相关产品推荐

