C# TreeView 控件的详解与应用小结

 更新时间:2026年01月30日 10:31:29   作者:工业程序猿老赵  
本文主要介绍了C# TreeView 控件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、TreeView 控件核心概念

TreeView 是 C# WinForm/WPF 中用于以树形层级结构展示数据的控件,其核心组成单元有两个:
1、TreeNode(树节点):TreeView 的最小展示单元,用于承载单个数据项,支持包含文本、图标、自定义数据等内容。
2、层级结构:TreeNode 支持嵌套(节点可以包含子节点),形成 “根节点 - 子节点 - 叶子节点” 的层级关系,根节点是树形结构的顶层节点(可多个),叶子节点是没有子节点的末端节点。
TreeView 常见应用场景:文件目录浏览、系统权限结构展示、菜单导航、数据分类层级展示等。

二、基础操作(WinForm 为例,最常用场景)

1. 环境准备

在 Visual Studio 中创建 WinForm 项目,从 “工具箱” 中拖拽 TreeView 控件到窗体上(默认命名为 treeView1),可通过属性窗口设置其外观(如大小、字体、背景色等)。

2. 核心:添加节点(TreeNode)

添加节点有设计时和运行时两种方式,运行时添加更具灵活性,是实际开发的主流方式。

  • (1)设计时添加
    选中 TreeView 控件,在属性窗口中找到 Nodes 属性,点击右侧 “…” 按钮,打开 “TreeNode 编辑器”,通过 “添加根”“添加子节点” 按钮创建层级结构,设置节点的 Text(显示文本)、Name(唯一标识)等属性,点击 “确定” 即可完成静态节点添加。
  • (2)运行时添加(3 种常用方式)

方式 1:直接创建 TreeNode 并添加(单个 / 少量节点)

// 1. 添加根节点
TreeNode rootNode1 = new TreeNode("计算机"); // 初始化节点,指定显示文本
treeView1.Nodes.Add(rootNode1); // 将根节点添加到 TreeView 的节点集合中

// 2. 给根节点添加子节点
TreeNode childNode1 = new TreeNode("本地磁盘 (C:)");
TreeNode childNode2 = new TreeNode("本地磁盘 (D:)");
rootNode1.Nodes.Add(childNode1); // 子节点添加到父节点的 Nodes 集合中
rootNode1.Nodes.Add(childNode2);

// 3. 嵌套添加孙子节点
TreeNode grandChildNode1 = new TreeNode("Windows 文件夹");
childNode1.Nodes.Add(grandChildNode1);

方式 2:批量添加节点(适合大量节点)

// 先创建节点数组,再批量添加
TreeNode[] rootNodes = new TreeNode[]
{
    new TreeNode("我的文档"),
    new TreeNode("我的图片"),
    new TreeNode("我的音乐")
};
treeView1.Nodes.AddRange(rootNodes); // 批量添加根节点

// 给“我的文档”批量添加子节点
TreeNode[] docChildNodes = new TreeNode[]
{
    new TreeNode("工作文档"),
    new TreeNode("个人文档"),
    new TreeNode("临时文档")
};
treeView1.Nodes[1].Nodes.AddRange(docChildNodes); // 通过索引获取根节点,再添加子节点数组

方式 3:简化写法(直接传入文本添加)

// 直接添加根节点(无需显式创建 TreeNode 实例)
treeView1.Nodes.Add("网络邻居");

// 给指定根节点添加子节点(链式写法)
treeView1.Nodes[3].Nodes.Add("无线网络");
treeView1.Nodes[3].Nodes.Add("有线网络");

3. 节点的常用操作(修改、删除、查找、展开 / 折叠)

  • (1)修改节点
// 1. 通过索引查找节点并修改文本
treeView1.Nodes[0].Text = "我的电脑(修改后)";

// 2. 通过节点名称查找并修改(设计时或创建时指定 Name 属性)
TreeNode targetNode = treeView1.Nodes.Find("nodeDoc", true)[0]; // true 表示递归查找所有子节点
targetNode.Text = "我的文档(修改后)";

// 3. 设置节点附加数据(Tag 属性,可存储任意对象)
childNode1.Tag = new { DiskType = "系统盘", Capacity = "500GB" };
  • (2)删除节点
// 1. 删除选中的节点
if (treeView1.SelectedNode != null)
{
    treeView1.SelectedNode.Remove();
}

// 2. 删除指定根节点
treeView1.Nodes.RemoveAt(3); // 删除索引为 3 的根节点

// 3. 清空所有节点
treeView1.Nodes.Clear();
  • (3)展开 / 折叠节点
// 1. 展开指定节点(包含所有子节点)
treeView1.Nodes[0].ExpandAll();

// 2. 折叠指定节点(包含所有子节点)
treeView1.Nodes[0].Collapse();

// 3. 切换节点的展开/折叠状态(点击节点时常用)
if (treeView1.SelectedNode != null)
{
    treeView1.SelectedNode.Toggle();
}

// 4. 展开所有根节点(不展开子节点)
foreach (TreeNode node in treeView1.Nodes)
{
    node.Expand();
}

三、关键事件:响应节点交互

TreeView 控件的核心交互事件用于捕获用户操作,最常用的有以下两个:

  1. AfterSelect 事件(节点选中后触发)
    当用户点击(或通过键盘切换)选中某个节点时触发,常用于获取选中节点的信息并执行后续逻辑。
    事件绑定与实现
// 方式1:通过窗体设计器绑定(选中 TreeView,双击属性窗口中的 AfterSelect 事件)
// 方式2:运行时手动绑定(窗体构造函数中)
public Form1()
{
    InitializeComponent();
    treeView1.AfterSelect += new TreeViewEventHandler(treeView1_AfterSelect);
}

// AfterSelect 事件处理方法
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
    // e.Node 表示当前选中的节点
    if (e.Node != null)
    {
        // 显示选中节点的信息
        string nodeInfo = $"选中节点:{e.Node.Text}\n节点层级:{GetNodeLevel(e.Node)}";
        if (e.Node.Tag != null)
        {
            nodeInfo += $"\n附加数据:{e.Node.Tag.ToString()}";
        }
        MessageBox.Show(nodeInfo);
    }
}

// 辅助方法:获取节点层级(根节点层级为 0)
private int GetNodeLevel(TreeNode node)
{
    int level = 0;
    TreeNode currentNode = node;
    while (currentNode.Parent != null)
    {
        level++;
        currentNode = currentNode.Parent;
    }
    return level;
}

2. NodeMouseClick 事件(节点鼠标点击触发)
当用户用鼠标点击节点时触发,可区分点击的鼠标按键(左键、右键),常用于实现右键菜单等功能。
事件实现(右键菜单示例)

// 窗体构造函数中绑定事件
public Form1()
{
    InitializeComponent();
    treeView1.NodeMouseClick += new TreeNodeMouseClickEventHandler(treeView1_NodeMouseClick);
}

// NodeMouseClick 事件处理方法
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    // 右键点击节点时显示自定义菜单
    if (e.Button == MouseButtons.Right)
    {
        // 选中当前点击的节点(避免右键点击未选中节点)
        treeView1.SelectedNode = e.Node;

        // 创建右键菜单
        ContextMenuStrip contextMenu = new ContextMenuStrip();
        contextMenu.Items.Add("查看节点信息");
        contextMenu.Items.Add("-"); // 分隔线
        contextMenu.Items.Add("修改节点文本");
        contextMenu.Items.Add("删除节点");

        // 菜单点击事件
        contextMenu.Items[0].Click += (s, args) =>
        {
            MessageBox.Show($"节点信息:{e.Node.Text}");
        };
        contextMenu.Items[2].Click += (s, args) =>
        {
            e.Node.Text = "修改后的节点(右键菜单)";
        };
        contextMenu.Items[3].Click += (s, args) =>
        {
            e.Node.Remove();
        };

        // 显示右键菜单
        contextMenu.Show(treeView1, e.Location);
    }
}

四、高级应用:动态加载树形数据(懒加载)

在实际开发中,若树形数据量较大(如文件目录、海量分类数据),一次性加载所有节点会导致界面卡顿,此时常用懒加载(按需加载):仅加载根节点,当用户展开某个节点时,再动态加载其下的子节点。
实现思路

  • 1、初始化时仅加载根节点,并给每个根节点标记 “未加载子节点”(可通过 Tag 属性或自定义节点扩展)。
  • 2、绑定 TreeView 的 BeforeExpand 事件(节点展开前触发)。
  • 3、在事件中判断当前节点是否已加载子节点,若未加载则动态获取数据并添加子节点,同时标记为 “已加载”。
    代码实现(模拟文件目录懒加载)
// 窗体构造函数:初始化根节点
public Form1()
{
    InitializeComponent();
    treeView1.BeforeExpand += new TreeViewCancelEventHandler(treeView1_BeforeExpand);
    
    // 初始化根节点(模拟“我的电脑”,标记为未加载子节点)
    TreeNode rootNode = new TreeNode("我的电脑");
    rootNode.Tag = false; // false = 未加载子节点,true = 已加载子节点
    treeView1.Nodes.Add(rootNode);
}

// BeforeExpand 事件:懒加载子节点
private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
    TreeNode currentNode = e.Node;
    // 判断是否已加载子节点(通过 Tag 属性判断)
    if (currentNode.Tag != null && (bool)currentNode.Tag == false)
    {
        // 清空临时节点(若有),避免重复加载
        currentNode.Nodes.Clear();

        // 模拟动态获取子节点数据(实际开发中可替换为数据库查询、文件目录读取等)
        List<string> childNodeNames = GetChildNodeData(currentNode.Text);

        // 添加子节点,并标记为未加载(后续可继续展开加载孙子节点)
        foreach (string nodeName in childNodeNames)
        {
            TreeNode childNode = new TreeNode(nodeName);
            childNode.Tag = false; // 子节点默认未加载孙子节点
            currentNode.Nodes.Add(childNode);
        }

        // 标记当前节点为已加载,避免重复触发加载
        currentNode.Tag = true;
    }
}

// 模拟获取子节点数据的方法
private List<string> GetChildNodeData(string parentNodeText)
{
    List<string> childNodes = new List<string>();
    switch (parentNodeText)
    {
        case "我的电脑":
            childNodes.AddRange(new string[] { "本地磁盘 (C:)", "本地磁盘 (D:)", "本地磁盘 (E:)" });
            break;
        case "本地磁盘 (C:)":
            childNodes.AddRange(new string[] { "Windows", "Program Files", "Users" });
            break;
        case "本地磁盘 (D:)":
            childNodes.AddRange(new string[] { "工作文件", "娱乐视频", "备份数据" });
            break;
        case "本地磁盘 (E:)":
            childNodes.AddRange(new string[] { "照片", "音乐", "软件安装包" });
            break;
        default:
            childNodes.Add("空文件夹");
            break;
    }
    return childNodes;
}

五、补充说明

  • 1、WPF 中的 TreeView:WinForm 的 TreeView 偏向传统桌面应用,WPF 中的 TreeView 支持数据绑定(ItemsSource)、模板自定义(DataTemplate),更适合现代化界面,核心思想(层级结构、节点操作)与 WinForm 一致,但实现方式更灵活。
  • 2、节点图标设置:可通过 ImageList 控件配合 TreeView 的 ImageList、ImageIndex、SelectedImageIndex 属性为节点设置普通状态和选中状态的图标。
  • 3、性能优化:处理大量节点时,可先调用 treeView1.BeginUpdate() 暂停界面刷新,操作完成后调用 treeView1.EndUpdate() 恢复刷新,避免界面闪烁。

六、总结

  • 1、TreeView 核心是TreeNode 节点的层级管理,节点的添加、删除、修改是基础操作,通过 Nodes 集合实现。
  • 2、常用交互依赖 AfterSelect(选中)和 NodeMouseClick(鼠标点击)事件,可满足大部分交互场景。
  • 3、大数据量场景下,** 懒加载(BeforeExpand 事件按需加载)** 是提升性能的关键。
  • 4、开发中可通过 Tag 属性存储节点附加数据,通过 BeginUpdate()/EndUpdate() 优化界面刷新性能。

到此这篇关于C# TreeView 控件的详解与应用小结的文章就介绍到这了,更多相关C# TreeView 控件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Unity实现图片水印生成

    Unity实现图片水印生成

    这篇文章主要为大家详细介绍了Unity实现图片水印生成,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#中Socket与Unity相结合示例代码

    C#中Socket与Unity相结合示例代码

    这篇文章主要给大家介绍了关于C#中Socket与Unity相结合的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-10-10
  • C#加锁防止并发的几种方法详解

    C#加锁防止并发的几种方法详解

    文章介绍了C#中多种加锁方式,包括lock、Monitor、SemaphoreSlim、Mutex、ReaderWriterLockSlim、Concurrent集合、Redis分布式锁,以及在实际工作中的应用和注意事项,感兴趣的朋友一起看看吧
    2025-03-03
  • 使用NOPI读取Word、Excel文档内容

    使用NOPI读取Word、Excel文档内容

    这篇文章主要为大家详细介绍了使用NOPI读取Word、Excel文档内容的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • 浅析如何使用C#实现在Excel中创建下拉列表

    浅析如何使用C#实现在Excel中创建下拉列表

    在日常的数据管理和分析中,Excel 扮演着不可或缺的角色,本文将为您介绍如何利用 C# 编程语言和强大的第三方库 Spire.XLS for .NET,自动化地在 Excel 中创建各种类型的下拉列表,感兴趣的小伙伴可以了解下
    2025-11-11
  • 实例讲解C# 泛型(Generic)

    实例讲解C# 泛型(Generic)

    这篇文章主要介绍了C# 泛型(Generic)的的相关资料,文中示例代码非常详细,帮助大家参考和学习,感兴趣的朋友可以了解下
    2020-06-06
  • WPF如何自定义TabControl控件样式示例详解

    WPF如何自定义TabControl控件样式示例详解

    这篇文章主要给大家介绍了关于WPF如何自定义TabControl控件样式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-04-04
  • C#实现Check Password和锁定输错密码锁定账户功能

    C#实现Check Password和锁定输错密码锁定账户功能

    C#实现的Check Password,并根据输错密码的次数分情况锁定账户:如果输入错误3次,登录账户锁定5分钟并提示X点X分后重试登录,具体实现代码感兴趣的朋友跟随小编一起看看吧
    2020-01-01
  • C#实现装箱与拆箱操作简单实例

    C#实现装箱与拆箱操作简单实例

    这篇文章主要介绍了C#实现装箱与拆箱操作,对于新手理解装箱与拆箱有一定的帮助,需要的朋友可以参考下
    2014-07-07
  • C#使用Spire.XLS for .NET将DataTable写入Excel的具体步骤

    C#使用Spire.XLS for .NET将DataTable写入Excel的具体步骤

    在日常开发中,我们经常需要将 DataTable 中的数据导出到 Excel 文件中,方便用户查看或进行后续分析,本文将介绍如何使用 Spire.XLS for .NET 实现这一功能,需要的朋友可以参考下
    2025-08-08

最新评论