C#高级:Winform桌面开发中TreeView的基础例子

一、方案一:免递归使用树

cs 复制代码
namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 自定义树实体
        /// </summary>
        public class WinFormTree
        {
            /// <summary>
            /// 标签名称
            /// </summary>
            public string Name { get; set; }
            /// <summary>
            /// 本节点ID(根节点Pid=0)
            /// </summary>
            public int Id { get; set; }
            /// <summary>
            /// 父节点ID
            /// </summary>
            public int Pid { get; set; }
        }

        //点击触发自定义弹窗输入
        private async void button1_Click(object sender, EventArgs e)
        {
            // 假设这是数据源
            List<WinFormTree> data = new List<WinFormTree>
            {
                new WinFormTree { Id = 1, Name = "爷爷", Pid = 0 },
                new WinFormTree { Id = 2, Name = "父亲", Pid = 1 },
                new WinFormTree { Id = 3, Name = "儿子", Pid = 2 },
                new WinFormTree { Id = 4, Name = "女儿", Pid = 2 } // 假设加个子节点
            };

            // 调用方法来构建树
            BuildTree(treeView1,data);
        }

        /// <summary>
        /// 构建树
        /// </summary>
        /// <param name="data"></param>
        private void BuildTree(TreeView treeView,List<WinFormTree> data)
        {
            //清空树
            treeView.Nodes.Clear();

            // 使用字典存储 id -> TreeNode 的映射
            Dictionary<int, TreeNode> nodeDict = new Dictionary<int, TreeNode>();

            // 根节点
            TreeNode rootNode = null;

            // 遍历所有数据,构建树
            foreach (var item in data)
            {
                TreeNode node = new TreeNode(item.Name);

                // 存储当前节点
                nodeDict.Add(item.Id, node);

                // 如果是根节点,保存根节点
                if (item.Pid == 0)
                {
                    rootNode = node;
                }
                else
                {
                    // 找到父节点并将当前节点添加到父节点下
                    if (nodeDict.ContainsKey(item.Pid))
                    {
                        nodeDict[item.Pid].Nodes.Add(node);
                    }
                }
            }

            // 将树根节点添加到 TreeView 中
            if (rootNode != null)
            {
                treeView.Nodes.Add(rootNode);
            }
        }

        /// <summary>
        /// 树节点选中事件(双击进入该方法)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            // 获取选中的节点的文本内容
            string selectedNodeText = e.Node.Text;

            // 将选中的节点文本设置到Label控件
            label1.Text = "选中的标签是: " + selectedNodeText;
        }
    }
}

二、方案二:递归求树

cs 复制代码
namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 自定义树实体
        /// </summary>
        public class WinFormTree
        {
            /// <summary>
            /// 标签名称
            /// </summary>
            public string Name { get; set; }
            /// <summary>
            /// 本节点ID(根节点Pid=0)
            /// </summary>
            public int Id { get; set; }
            /// <summary>
            /// 父节点ID
            /// </summary>
            public int Pid { get; set; }
        }

        //点击触发自定义弹窗输入
        private async void button1_Click(object sender, EventArgs e)
        {
            // 假设这是数据源
            List<WinFormTree> data = new List<WinFormTree>
            {
                new WinFormTree { Id = 1, Name = "爷爷", Pid = 0 },
                new WinFormTree { Id = 2, Name = "父亲", Pid = 1 },
                new WinFormTree { Id = 3, Name = "儿子", Pid = 2 },
                new WinFormTree { Id = 4, Name = "女儿", Pid = 2 } // 假设加个子节点
            };

            // 调用方法来构建树
            BuildTree(treeView1,data);
        }

        /// <summary>
        /// 构建树
        /// </summary>
        /// <param name="data"></param>
        private void BuildTree(TreeView treeView,List<WinFormTree> data)
        {
            //清空树
            treeView.Nodes.Clear();

            // 根节点
            TreeNode rootNode = GetTreeByData(data);

            // 将树根节点添加到 TreeView 中
            if (rootNode != null)
            {
                treeView.Nodes.Add(rootNode.FirstNode);
            }
        }
        private TreeNode GetTreeByData(List<WinFormTree> data, int parentId = 0)
        {
            // 使用 LINQ 获取所有子节点
            var nodes = data
                .Where(x => x.Pid == parentId)
                .Select(item =>
                {
                    var node = new TreeNode(item.Name);
                    node.Nodes.AddRange(GetTreeByData(data, item.Id).Nodes.Cast<TreeNode>().ToArray()); // 递归添加子节点
                    return node;
                })
                .ToList();

            // 创建一个父节点并将子节点添加进去
            var parentNode = new TreeNode();
            parentNode.Nodes.AddRange(nodes.ToArray());  // 添加所有子节点
            return parentNode;
        }





        /// <summary>
        /// 树节点选中事件(双击进入该方法)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            // 获取选中的节点的文本内容
            string selectedNodeText = e.Node.Text;

            // 将选中的节点文本设置到Label控件
            label1.Text = "选中的标签是: " + selectedNodeText;
        }
    }
}

三、效果图

相关推荐
AIFQuant5 小时前
Java 对接全球股票实时报价:高可用架构与异常处理
java·开发语言·websocket·金融·架构·股票api
Huangjin007_6 小时前
【C++ STL篇(十)】深入理解 AVL 树:代码实现、旋转图解与平衡因子详解
开发语言·c++
小明同学016 小时前
C++后端项目:统一大模型接入 SDK(四)
服务器·开发语言·c++·计算机网络·chatgpt
安妮的小熊呢6 小时前
CRMEB开源商城系统 & 标准版系统(PHP)开发规范
开发语言·javascript·php
子榆.6 小时前
CANN ATC编译器:模型从Python到达芬奇指令走了多远
开发语言·python·neo4j
Dontla6 小时前
Multi-Agent多智能体项目如何从MVP过渡到生产项目?
开发语言
兰令水6 小时前
topcode【随机算法题】【2026.5.20打卡-java版本】
java·开发语言·算法
我还记得那天7 小时前
C语言递归实现汉诺塔问题
c语言·开发语言
魔法阵维护师7 小时前
从零开发游戏需要学习的c#模块,第十三章(rpg小游戏入门,下篇,地图敌人与战斗触发)
学习·游戏·c#
不吃土豆的马铃薯7 小时前
Spdlog 入门:日志记录器与日志槽基础详解
服务器·开发语言·c++·c·日志·spdlog