一、效果图(整个项目源码)
1、选择父结点,所有子节点自动勾选
2、取消父结点的选择,子节点也全部取消
3、勾选子节点,自动勾选所有祖先结点
4、子节点取消勾选,先判断该父结点下是否还有其他子节点被勾选,如果有则不取消,没有则取消。
二、实现
首先设置TreeView控件中的CheckBoxes为true,这样在显示菜单时每项菜单前会有一个勾选框。
private void editTreeView_AfterCheck(object sender, TreeViewEventArgs e)//勾选事件
{
if (e.Action == TreeViewAction.ByMouse)
//当该事件是由鼠标点击触发时才发生,否则设置该结点的Checked为true也会导致该事件发生
{
if (e.Node.Checked)//勾选结点时
{
setParentNodeChecked(e.Node);//勾选所有祖先结点
setChildNodeChecked(e.Node);//勾选所有子节点
}
else//取消勾选时
{
setChildNodeCancel(e.Node);//取消所有子节点
setParentNodeCancel(e.Node);//处理祖先结点,需判断
}
}
}
private void setChildNodeCancel(TreeNode node)//取消所有子节点的选择
{
foreach (TreeNode a in node.Nodes)
{
if (a != null)
{
a.Checked = false;
setChildNodeCancel(a);
}
}
}
private void setParentNodeCancel(TreeNode node)//取消祖先结点选择
{
if(node.Parent!=null&& judegChildChecked(node.Parent))
{
TreeNode parent;
node.Parent.Checked = false;
parent = node.Parent;
setParentNodeCancel(parent);
}
}
private void setParentNodeChecked(TreeNode t)//选择所有祖先结点
{
TreeNode parent = t.Parent;
while(parent!=null && parent.Checked == false)
{
parent.Checked = true;
parent = parent.Parent;
}
}
private void setChildNodeChecked(TreeNode t)//勾选所有子节点
{
foreach(TreeNode a in t.Nodes)
{
if (a != null)
{
a.Checked = true;
setChildNodeChecked(a);
}
}
}
private bool judegChildChecked(TreeNode t)//判断其子节点是否有勾选状态
{
foreach(TreeNode a in t.Nodes)
{
if(a != null && a.Checked == true)
{
return false;
}
}
return true;
}