首先要注册treeview中的aftercheck事件
要编辑3个方法
/// <summary>
/// 选中父节点所有子节点被选中
/// </summary>
/// <param name="n">当前选中节点</param>
/// <param name="check">是否被选中</param>
private void cycleChild(TreeNode n, bool check)
{
if (n.Nodes.Count !=0)
{
foreach (TreeNode child in n.Nodes)
{
child.Checked = check;
if (child.Nodes.Count!=0)
{
cycleChild(child, check);
}
}
}
}
/// <summary>
/// 遍历父节点如果子节点选中则全部选中,子节点没有选中则父节点不选中
/// </summary>
/// <param name="n"></param>
/// <param name="check"></param>
private void cycleParent(TreeNode n, bool check)
{
if (n.Parent!=null)
{
if (nextCheck(n))
{
n.Parent.Checked = true;
}
else
{
n.Parent.Checked = false;
}
cycleParent(n.Parent, check);
}
}
/// <summary>
/// 判断通级节点是否全选
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
private bool nextCheck(TreeNode n)
{
foreach (TreeNode node in n.Parent.Nodes)
{
if (node.Checked==false)
{
return false;
}
}
return true;
}
最后在aftercheck事件中编辑
//需要加上e.action!=treeviewaction.unknown在加载窗体的时候不触发该事件
if (e.Action != TreeViewAction.Unknown)
{
//如果对应的父节点被选中,对应的子节点全部被选中
if (e.Node.Checked == true)
{
cycleChild(e.Node, true);
if (e.Node.Parent != null)
{
//如果对应的父节点的其中一个子节点没有被选中父节点不选中,如果对应的子节点全部选中父节点选中
if (nextCheck(e.Node))
{
cycleParent(e.Node, true);
}
else
{
cycleParent(e.Node, false);
}
}
}
//如果对应的父节点没被选中,对应的子节点与父节点全部不选中
if (e.Node.Checked == false)
{
cycleParent(e.Node, false);
cycleChild(e.Node, false);
}
}