WPF TreeView无法显示AdOu类三层及以下嵌套节点问题求助
WPF TreeView无法加载AD OU三层及以下节点的问题
我在WPF TreeView中尝试重现Active Directory组织单元(OU)的层级结构,使用HierarchicalDataTemplate绑定AdOu类的Items属性。给不可变字段添加getter和setter后,TreeView仅能加载根节点和一级子节点,三层及以下的节点无法正常显示。
相关代码
XAML资源定义
<Window.Resources> <DataTemplate x:Key="treeviewou"> <TextBlock Text="{Binding Name}" /> </DataTemplate> <HierarchicalDataTemplate x:Key="treeviewitems" DataType="{x:Type admodels:AdOu}" ItemsSource="{Binding Items}" ItemTemplate="{StaticResource treeviewou}"> <StackPanel> <TextBlock Text="{Binding Name}" /> </StackPanel> </HierarchicalDataTemplate> </Window.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="83*"/> <ColumnDefinition Width="317*"/> </Grid.ColumnDefinitions> <DataGrid x:Name="grdUsers" Grid.Column="1" d:ItemsSource="{d:SampleData ItemCount=5}"/> <TreeView x:Name="tvOus" SelectedItemChanged="tvOus_SelectedItemChanged" ItemTemplate="{StaticResource treeviewitems}"> </TreeView> </Grid>
AdOu类定义
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.DirectoryServices; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ADUtils.Models { public class AdOu : ViewModelBase { private SearchResult? _searchResult; private DirectoryEntry? _directoryEntry; private string? _name; public List<AdOu> Items { get; set; } = new List<AdOu>(); public AdOu(SearchResult sr) { searchResult = sr; } public AdOu(DirectoryEntry de) { directoryEntry = de; } public SearchResult? searchResult { get { if (_searchResult == null && directoryEntry != null) { DirectoryEntry startingPoint = new DirectoryEntry(directoryEntry.Path); DirectorySearcher searcher = new DirectorySearcher(startingPoint); searcher.SearchScope = SearchScope.Base; _searchResult = searcher.FindOne(); } return _searchResult; } set { _searchResult = value; OnPropertyChanged(nameof(Name)); } } public DirectoryEntry? directoryEntry { get { if (_directoryEntry == null && searchResult != null) { _directoryEntry = searchResult.GetDirectoryEntry(); } return _directoryEntry; } set { _directoryEntry = value; OnPropertyChanged(nameof(Name)); } } public string? Name { get { if (_name == null && searchResult != null && searchResult.Properties["Name"].Count > 0) { _name = searchResult.Properties["Name"][0].ToString(); } return _name; } } } }
初始化TreeView代码
public void InitTreeView() { ListOus = adOUs.GetHierarchical(); TreeViewList = new ObservableCollection<AdOu>(ListOus); tvOus.ItemsSource = TreeViewList; } private ADTreeViewItem OusToTreeView(AdOu? ou = null, ADTreeViewItem? parent = null) { ADTreeViewItem tviRoot = new ADTreeViewItem(ou); foreach (AdOu child in ou?.Items ?? ListOus ?? new List<AdOu>()) { OusToTreeView(child, tviRoot); } if (parent != null) { parent.Items.Add(tviRoot); } return tviRoot; }
解决方案
1. 修正HierarchicalDataTemplate配置
问题核心在于当前的HierarchicalDataTemplate给子节点指定了普通DataTemplate,该模板没有绑定子节点的Items集合,导致二级及以下节点无法展开。修改模板,让它递归应用层级模板:
<Window.Resources> <HierarchicalDataTemplate x:Key="treeviewitems" DataType="{x:Type admodels:AdOu}" ItemsSource="{Binding Items}"> <TextBlock Text="{Binding Name}" /> </HierarchicalDataTemplate> </Window.Resources>
这样每个AdOu节点都会自动使用这个层级模板,子节点也会递归绑定Items,从而显示所有层级的节点。
2. 验证层级数据结构
确保adOUs.GetHierarchical()方法正确构建了OU的层级关系:
- 根节点的
Items集合包含所有一级子OU - 每个一级子OU的
Items集合包含对应的二级子OU,以此类推
如果数据本身没有正确嵌套,模板配置再正确也无法显示深层节点。
3. 优化集合类型(可选)
将AdOu类中的Items从List<AdOu>改为ObservableCollection<AdOu>,这样后续动态添加/删除子节点时,TreeView会自动更新UI:
public ObservableCollection<AdOu> Items { get; set; } = new ObservableCollection<AdOu>();
内容的提问来源于stack exchange,提问作者DerpyNerd
相关产品推荐
相关产品推荐

