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;
        }
    }
}

三、效果图

相关推荐
Wang's Blog3 分钟前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
曹牧29 分钟前
C#:输入的字符串格式不正确
c#
程序喵大人2 小时前
【C++入门】编译链接模型 - 07 链接器怎样把符号对上号
开发语言·c++·编译器·编译链接·链接器
微三云 - 廖会灵 (私域系统开发)2 小时前
供应链系统实战:多渠道订单聚合与分布式库存一致性方案总结
开发语言·分布式·php
学逆向的3 小时前
C 数据溢出与精度丢失
c语言·开发语言·网络安全
霸道流氓气质3 小时前
AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排
java·开发语言
释厄6234 小时前
错误无误公理——错误正确本同源都迭代定律——逆转有价值
android·开发语言·kotlin
2601_962885724 小时前
如何用 Python计算 CR能量指标(中间意愿指标)?
开发语言·python
临床数据科学和人工智能兴趣组4 小时前
在R语言的生态系统中,字符串处理一直是一个重要且复杂的任务
开发语言·正则表达式·r语言·r语言-4.2.1
蜗牛互联网5 小时前
Python调用Gemini Structured Outputs实现工单路由门禁
java·开发语言·人工智能·python