C# TreeView 建立、遍历树(递归)

刚接触treeview这个功能,恶补了几天,博主总结下实现的功能以备用,希望能帮到需要的亲~~

C#gui程序中建立树状结构、遍历树状结构、树状结构节点选中联动(选中父节点时,自动选中其全部子节点,取消选中的某子节点,取消其相应的所有父节点的选中),读取选中节点信息。

0.最初的父节点建立

ParentNode = tv_user.Nodes.Add(OUname);
tv_user.CheckBoxes = true; //表示节点可以进行选中/取消选中操作

1、增加树的子节点

写了一个函数,(递归调用)实现无限级树结构
此代码是用于遍历AD域,然后输出某部门的树状组织结构

关于AD域请参考上篇文章:http://blog.csdn.net/heivy/article/details/53505916

ouName :是某部门名称

 public void AddTree(TreeNode pNode, string ouName, DirectoryEntry objDE)
        {
            TreeNode pnode = pNode, cnode;

            DirectorySearcher objSearch = new DirectorySearcher(objDE);
            objSearch.Filter = "(&(objectClass=organizationalUnit)(ou=" + ouName + "))";
            SearchResult objsearchResult = objSearch.FindOne();
            DirectoryEntry objEntry = objsearchResult.GetDirectoryEntry();

            foreach (DirectoryEntry entry in objEntry.Children)
            {
            //如果节点是组织单元(即部门)(即存在子节点),则调用函数AddTree()
                if (entry.SchemaClassName.Equals("organizationalUnit"))
                {
                    cnode = pnode.Nodes.Add(entry.Properties["name"][0].ToString());

                    AddTree(cnode, entry.Properties["name"][0].ToString(), objDE);
                }
                //如果节点是群组(即存在子节点),则调用函数AddTree()
                else if (entry.SchemaClassName.Equals("group"))
                {
                    cnode = pnode.Nodes.Add(entry.Properties["name"][0].ToString());

                    int count = entry.Properties["member"].Count;

                    string memberName = "";
                    for (int i = 1; i < count; i++)
                    {
                        string tmpName = entry.Properties["member"][i].ToString();
                        memberName = tmpName.Split(',')[0].Split('=')[1].ToString();
                        cnode.Nodes.Add(memberName);
                    }
                }
                else
                {
                    cnode = pnode.Nodes.Add(entry.Properties["name"][0].ToString());
                }
            }
        }

2.遍历树(读取被选中节点的信息)

public List<string> CheckedNodes(TreeNode parent, List<string> checkednodes)
        {

            TreeNode node = parent;
            if (node != null)
            {
                if (node.Checked == true && node.FirstNode == null)
                    checkednodes.Add(node.Text);

                if (node.FirstNode != null)////如果node节点还有子节点则进入遍历
                {
                    CheckedNodes(node.FirstNode, checkednodes);
                }
                if (node.NextNode != null)////如果node节点后面有同级节点则进入遍历
                {
                    CheckedNodes(node.NextNode, checkednodes);
                }
            }

            return checkednodes;
        }

3、节点选中联动功能

在treeview_AfterCheck 事件中调用下面2个函数,如:

if (e.Action == TreeViewAction.ByMouse)
            {
                // textBox1.Text = e.Node.Text;
                if (e.Node.Checked == true)
                {
                    //选中节点之后,选中该节点所有的子节点
                    setChildNodeCheckedState(e.Node, true);

                }
                else if (e.Node.Checked == false)
                {
                    //取消节点选中状态之后,取消该节点所有子节点选中状态
                    setChildNodeCheckedState(e.Node, false);
                    //如果节点存在父节点,取消父节点的选中状态
                    if (e.Node.Parent != null)
                    {
                        setParentNodeCheckedState(e.Node, false);
                    }
                }
            }

下面是实现节点选中联动的2个子函数:

    //取消节点选中状态之后,取消所有父节点的选中状态
        public void setParentNodeCheckedState(TreeNode currNode, bool state)
        {
            TreeNode parentNode = currNode.Parent;
            parentNode.Checked = state;
            if (currNode.Parent.Parent != null)
            {
                setParentNodeCheckedState(currNode.Parent, state);
            }
        }
        //选中节点之后,选中节点的所有子节点
        public void setChildNodeCheckedState(TreeNode currNode, bool state)
        {
            TreeNodeCollection nodes = currNode.Nodes;
            if (nodes.Count > 0)
            {
                foreach (TreeNode tn in nodes)
                {
                    tn.Checked = state;
                    setChildNodeCheckedState(tn, state);
                }
            }
        }

参考:

本文出自he ivy 的博客,转载请注明出处:http://blog.csdn.net/heivy/article/details/53507257

  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
//设定生成的原始数据 void getdatable() { tblDatas.Columns.Add("groupid", Type.GetType("System.String")); tblDatas.Columns.Add("groupname", Type.GetType("System.String")); tblDatas.Columns.Add("parentid", Type.GetType("System.String")); tblDatas.Rows.Add(new object[] { "1", "机关", "0" }); tblDatas.Rows.Add(new object[] { "2", "学院", "0" }); tblDatas.Rows.Add(new object[] { "3", "教学管理中心", "1" }); tblDatas.Rows.Add(new object[] { "4", "校园管理中心", "1" }); tblDatas.Rows.Add(new object[] { "5", "数据中心", "3" }); tblDatas.Rows.Add(new object[] { "6", "信息中心", "3" }); tblDatas.Rows.Add(new object[] { "7", "一卡通", "4" }); tblDatas.Rows.Add(new object[] { "8", "保卫处", "4" }); tblDatas.Rows.Add(new object[] { "9", "信工系", "2" }); tblDatas.Rows.Add(new object[] { "10", "艺术系", "2" }); dataGridView1.DataSource = tblDatas; } //递归生成函数 public void AddTree(int ParentID, TreeNode pNode) { DataTable dt = new DataTable(); dt = tblDatas; DataView dvTree = new DataView(dt); //过滤ParentID,得到当前的所有子节点 dvTree.RowFilter = "parentid = " + ParentID; foreach (DataRowView Row in dvTree) { TreeNode Node = new TreeNode(); if (pNode == null) { //添加根节点 Node.Text = Row["groupname"].ToString(); treeView1.Nodes.Add(Node); AddTree(Int32.Parse(Row["groupid"].ToString()), Node); //再次递归 } else { //添加当前节点的子节点 Node.Text = Row["groupname"].ToString(); pNode.Nodes.Add(Node); AddTree(Int32.Parse(Row["groupid"].ToString()), Node); //再次递归 } } } //调用递归函数在treeView1里面显示给出数据的形图 private void button1_Click(object sender, EventArgs e) { treeView1.Nodes.Clear(); AddTree(0, (TreeNode)null); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heivy

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值