C#递归遍历树节点并且存储

前面介绍了TreeView控件生成树,TreeView控件在C#开发中用处很广泛,这里就把我再实际使用的过程中用到的方法总结一下。

1.点击TreeView某一节点,将该节点所有子节点遍历存储。

比如我们想知道父节点下的所有子节点。

我们首先定义一个List 来存储节点

List m_SubNode = new List();
递归遍历节点并且存储子节点

private void RecursionSaveNode(TreeNode tn)
{        
     foreach (TreeNode tnSub in tn.Nodes)
     {
           m_SubNode.Add(tnSub.Text); //注意这个位置加上Text,如果写成tnSub.ToString(),那存储的就不是名字了,而是"TreeNode:名字",多了一个TreeNode:字符
           RecursionSaveNode(tnSub);  
     }
}
实际调用过程中

m_SubNode.Clear();
m_SubNode.Add(treeView.SelectedNode.Text); //这句话把点击的父节点也存储了,如果不需要查看父节点,把这句话注释即可。
RecursionSaveNode(treeView.SelectedNode);
2. 存储指定的节点,如果在TreeView中加了复选框,来查看TreeView节点是否勾选的状态。

如果父节点勾选,那么所有的子节点都要勾选,如果父节点取消勾选,那么所有子节点都要取消勾选,子节点的勾选一般不会影响父节点,但是如果所有的子节点都取消勾选,那么父节点才取消勾选,如果有一个子节点勾选了,那么父节点也要勾选。

(1)父节点与子节点的逻辑判断

设置子节点的状态。设置子节点的状态很简单,只用把子节点的状态设成跟父节点一样就行了,递归遍历设置所有的子节点即可。

 private void setchild(TreeNode node)
 {
        foreach (TreeNode child in node.Nodes)
        {
                child.Checked = node.Checked; //子节点状态与父节点一样
                setchild(child);
        }         
 }
设置父节点的状态

设置父节点的状态稍微麻烦一些,首先需要判断父节点是否存在,如果不存在则返回,如果存在再进行判断,如果父节点所有的子节点都取消勾选,则父节点取消勾选,如果有一个子节点勾选,则父节点勾选

private void setparent(TreeNode node)
{
            if (node.Parent != null)
            {
                if (node.Checked)
                {
                    node.Parent.Checked = node.Checked;
                    return;
                }
                else
                {   //判断兄弟节点对父节点的影响
                    //全部不选则不选,否则勾选
                    foreach (TreeNode brother in node.Parent.Nodes) //兄弟节点就是父节点的子节点
                    {
                        if (brother.Checked == false)
                            continue;
                        else
                            return;
                    }
                    node.Parent.Checked = false;
                }
            }
}
实际调用,实际调用的过程中父子节点的判断写在treeView_AfterCheck事件里面,有一点需要注意,如果是在TreeView加载的过程中就勾选了树节点,那么TreeView初始化时就会触发这个事件,这里就需要屏蔽窗口加载时触发这个事件。

private void treeView_AfterCheck(object sender, TreeViewEventArgs e)
{
            if (e.Action!=TreeViewAction.Unknown) //屏蔽TreeView加载时调用这个事件,只有手动点击TreeView才能触发下面的代码
            {
                setchild(e.Node);
                setparent(e.Node);
            }               
}
这里也许有人会问,我要一开始就要把所有的子节点都打上勾,那该怎么办?这里我是单独写了一个函数,初始化勾选所有节点,如果用 treeView_AfterCheck初始化,会显得挺乱,我把初始化与勾选判断分开来。

private void InitTreeView(TreeNode tn)
{
            foreach (TreeNode tnSub in tn.Nodes)
            {
                tnSub.Checked = true;
                InitTreeView(tnSub);

            }
}
实际调用的过程中,把第一个节点初始化,调用该函数即可。

treeView.Nodes[0].Checked = true;
InitTreeView(treeView1.Nodes[0]);
(2)存储未选中(选中)的节点,判断未选中(选中)的节点

判断未选中的节点并且存储只用在1中的例子加个判断即可

private void RecursionSaveUnCheckNode(TreeNode tn)
{
            foreach (TreeNode tnSub in tn.Nodes)
            {
                if (tnSub.Checked == false)
                {
                    m_SubUncheckedNode.Add(tnSub.Text);
                    RecursionSaveUnCheckNode(tnSub);
                }

            }
 }


private void RecursionSaveCheckNode(TreeNode tn)
{
            foreach (TreeNode tnSub in tn.Nodes)
            {
                if (tnSub.Checked == true)
                {
                    m_SubCheckedNode.Add(tnSub.Text);
                    RecursionSaveCheckNode(tnSub);
                }
            }
}

实际调用的过程中

m_SubUnCheckedNode.Clear();
RecursionSaveUnCheckNode(treeView.SelectedNode);

m_SubCheckedNode.Clear();
RecursionSaveCheckNode(treeView.SelectedNode);

3.节点的访问

TreeView的节点可以通过数组来进行访问,例如我要访问根节点,则可以这么写treeView.Nodes[0],或者访问根节点下的第三的节点,treeView.Nodes[0].Nodes[2]
点XXX.Nodes代表节点XXX的子节点
某一节点的父节点  treeView.Nodes[XXX].Parent












你可能感兴趣的:(C#应用开发,C#应用开发笔记)