WPF TreeView绑定多类异常:CADModel子节点无法正常显示
问题描述
已成功将WPF TreeView绑定到ClassModel,但部分ClassModel需要包含子CADModel,当前层级数据模板无法正常工作。预期每个ClassModel节点下显示名为"Bob"的CADModel叶子节点,实际未达成该效果。
相关代码
XAML代码
<TreeView.Resources> <!-- HierarchicalDataTemplate for ClassModel --> <HierarchicalDataTemplate DataType= "{x:Type models:ClassModel}" ItemsSource = "{Binding Path=ChildClasses}"> <TextBlock Text="{Binding Path=ClassName}"/> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type models:CADModel}"> <TextBlock Text="{Binding Path=PartNumber}"/> </DataTemplate> </TreeView.Resources>
C# 实体类代码
IClassModel接口与ClassModel实现
public interface IClassModel : ITreeNode { ObservableCollection<ClassModel> ChildClasses { get; set; } ObservableCollection<CADModel>? CADModels { get; set; } int ClassId { get; set; } int ParentClassId { get; set; } string ClassName { get; set; } bool HasChildClass { get; set; } LibraryModel? ParentLibrary { get; set; } } public class ClassModel : TreeNode, IClassModel { public LibraryModel? ParentLibrary { get; set; } = null; public int ParentClassId { get; set; } = 0; public int ClassId { get; set; } = 0; public string ClassName { get; set; } = string.Empty; public bool HasChildClass { get; set; } = false; public ObservableCollection<ClassModel> ChildClasses { get; set; } = new ObservableCollection<ClassModel>(); public ObservableCollection<CADModel>? CADModels { get; set; } = null; public ClassModel() { if (HasChildClass == false) { CADModels = new ObservableCollection<CADModel>() { new CADModel() { Id = 0, PartNumber = "Bob", Revision = "A.1" } }; } } }
ICADModel接口与CADModel实现
public interface ICADModel : ITreeNode { string PartNumber { get; set; } string Revision { get; set; } } public class CADModel :TreeNode, ICADModel { public string PartNumber { get; set; } = string.Empty; public string Revision { get; set; } = string.Empty; }
当前TreeView显示效果

解决方案
问题核心是当前HierarchicalDataTemplate仅绑定了ChildClasses集合,TreeView无法自动识别ClassModel中的CADModels子节点。以下两种方法可解决该问题:
方法1:在ClassModel中添加合并后的子集合
给ClassModel新增一个只读属性,合并ChildClasses和CADModels两个集合:
public class ClassModel : TreeNode, IClassModel { // 保留原有所有属性... public IEnumerable<object> Children { get { foreach (var childClass in ChildClasses) yield return childClass; if (CADModels != null) { foreach (var cadModel in CADModels) yield return cadModel; } } } }
修改XAML中的HierarchicalDataTemplate,将ItemsSource绑定到新的Children属性:
<HierarchicalDataTemplate DataType="{x:Type models:ClassModel}" ItemsSource="{Binding Path=Children}"> <TextBlock Text="{Binding Path=ClassName}"/> </HierarchicalDataTemplate>
方法2:在XAML中使用CompositeCollection合并集合
无需修改C#代码,直接在XAML中通过CompositeCollection合并两个子集合:
<HierarchicalDataTemplate DataType="{x:Type models:ClassModel}"> <TextBlock Text="{Binding Path=ClassName}"/> <HierarchicalDataTemplate.ItemsSource> <CompositeCollection> <CollectionContainer Collection="{Binding Path=ChildClasses}"/> <CollectionContainer Collection="{Binding Path=CADModels}"/> </CompositeCollection> </HierarchicalDataTemplate.ItemsSource> </HierarchicalDataTemplate>
注意:使用该方法时,建议将ClassModel中CADModels的初始值设为空集合而非null,避免绑定错误。
内容的提问来源于stack exchange,提问作者Marc
相关产品推荐
相关产品推荐

