You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:45:43