WPF TreeView数据绑定代码仅显示一级数据,请求修正
WPF TreeView仅显示第一级数据的修正方案
问题背景
我是C#与WPF的初学者,在研究TreeView数据绑定方法时,参考了HierarchicalDataTemplate相关示例,自行编写了实体类及XAML代码,但运行后TreeView仅能展示第一级数据。以下是我的原始代码:
原始实体类:ListLeagueList
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections.ObjectModel; namespace Treeview01 { public class ListLeagueList : ObservableCollection<League> { public ListLeagueList() : base() { Add(new League("League A")); Add(new League("League B")); Add(new League("League C")); } } }
原始实体类:League
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections.ObjectModel; namespace Treeview01 { public class League { public string Name { get; set; } List<Division> Divisions = new List<Division>(); public League(string name) { Name = name; Divisions.Add(new Division("DivisionA")); Divisions.Add(new Division("DivisionB")); Divisions.Add(new Division("DivisionC")); } private League() { } } }
原始实体类:Division
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections.ObjectModel; namespace Treeview01 { public class Division { public string Name { get; set; } List<Team> Teams = new List<Team>(); public Division(string name) { Name = name; Teams.Add(new Team("Bear")); Teams.Add(new Team("Rocket")); } private Division() { } } }
原始实体类:Team
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Treeview01 { public class Team { public string Name { get; set; } public Team(string name) { Name = name; } private Team() { } } }
原始XAML代码
<Window x:Class="Treeview01.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="HierarchicalDataTemplate Sample" xmlns:src="clr-namespace:Treeview01"> <DockPanel> <DockPanel.Resources> <src:ListLeagueList x:Key="MyList"/> <HierarchicalDataTemplate DataType = "{x:Type src:League}" ItemsSource = "{Binding Path=Divisions}"> <TextBlock Text="{Binding Path=Name}"/> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType = "{x:Type src:Division}" ItemsSource = "{Binding Path=Teams}"> <TextBlock Text="{Binding Path=Name}"/> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type src:Team}"> <TextBlock Text="{Binding Path=Name}"/> </DataTemplate> </DockPanel.Resources> <Menu Name="menu1" DockPanel.Dock="Top" Margin="10,10,10,10"> <MenuItem Header="My Soccer Leagues" ItemsSource="{Binding Source={StaticResource MyList}}" /> </Menu> <TreeView> <TreeViewItem ItemsSource="{Binding Source={StaticResource MyList}}" Header="My Soccer Leagues" /> </TreeView> </DockPanel> </Window>
原始XAML.CS代码
using System.Windows; namespace Treeview01 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } } }
运行后仅显示第一级数据:
问题原因
核心问题是实体类中的子集合(Divisions、Teams)为私有字段,WPF数据绑定机制只能访问公共属性,无法识别私有字段,因此子级数据无法被HierarchicalDataTemplate加载展示。
修正方案
将实体类中的私有子集合字段改为公共的只读属性,推荐使用ObservableCollection<T>替代List<T>(支持集合变更通知,后续修改集合时UI能自动更新)。
修正后的League类
using System; using System.Collections.ObjectModel; namespace Treeview01 { public class League { public string Name { get; set; } // 改为公共只读ObservableCollection属性 public ObservableCollection<Division> Divisions { get; } = new ObservableCollection<Division>(); public League(string name) { Name = name; Divisions.Add(new Division("DivisionA")); Divisions.Add(new Division("DivisionB")); Divisions.Add(new Division("DivisionC")); } private League() { } } }
修正后的Division类
using System; using System.Collections.ObjectModel; namespace Treeview01 { public class Division { public string Name { get; set; } // 改为公共只读ObservableCollection属性 public ObservableCollection<Team> Teams { get; } = new ObservableCollection<Team>(); public Division(string name) { Name = name; Teams.Add(new Team("Bear")); Teams.Add(new Team("Rocket")); } private Division() { } } }
其他代码保持不变
ListLeagueList、Team类及XAML、XAML.CS代码无需修改。
效果验证
修改后运行程序,TreeView将正常展示所有层级的数据(联赛→分区→球队),Menu控件也会同步显示完整层级。
内容的提问来源于stack exchange,提问作者Colin
相关产品推荐
相关产品推荐

