C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C# TreeView 控件

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

作者:工业程序猿老赵

本文主要介绍了C# TreeView 控件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、TreeView 控件核心概念

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

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

1. 环境准备

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

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

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

方式 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. 通过索引查找节点并修改文本
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" };
// 1. 删除选中的节点
if (treeView1.SelectedNode != null)
{
    treeView1.SelectedNode.Remove();
}

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

// 3. 清空所有节点
treeView1.Nodes.Clear();
// 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);
    }
}

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

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

// 窗体构造函数:初始化根节点
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;
}

五、补充说明

六、总结

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

您可能感兴趣的文章:
阅读全文