前面介绍了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