TreeView树中节点勾选要求:
1、不选中一个节点,则其所有的子节点都不被选中。
2、选中一个节点,则其所有的子节点都被选中。
3、当一个节点的所有子节点都没有被选中时,该节点也没有被选中。
4、当一个节点的所有子节点中有一个被选中时,则该节点也被选中。
代码中对事件参数e.Action的判断,可以避免在改变节点的Checked的状态时,再次进入AfterCheck(),这样当在AfterCheck()中有其他逻辑响应时,可以做到每次勾选时,其他逻辑也只响应一次。
参考代码:
private void treeView_AfterCheck(object sender, TreeViewEventArgs e) { //通过鼠标或者键盘触发事件,防止修改节点的Checked状态时候再次进入 if (e.Action == TreeViewAction.ByMouse || e.Action == TreeViewAction.ByKeyboard) { SetChildNodeCheckedState(e.Node, e.Node.Checked); SetParentNodeCheckedState(e.Node, e.Node.Checked); } } //设置子节点状态 private void SetChildNodeCheckedState(TreeNode currNode, bool isCheckedOrNot) { if (currNode.Nodes == null) return; //没有子节点返回 foreach (TreeNode tmpNode in currNode.Nodes) { tmpNode.Checked = isCheckedOrNot; SetChildNodeCheckedState(tmpNode, isCheckedOrNot); } } //设置父节点状态 private void SetParentNodeCheckedState(TreeNode currNode, bool isCheckedOrNot) { if (currNode.Parent == null) return; //没有父节点返回 if (isCheckedOrNot) //如果当前节点被选中,则设置所有父节点都被选中 { currNode.Parent.Checked = isCheckedOrNot; SetParentNodeCheckedState(currNode.Parent, isCheckedOrNot); } else //如果当前节点没有被选中,则当其父节点的子节点有一个被选中时,父节点被选中,否则父节点不被选中 { bool checkedFlag = false; foreach (TreeNode tmpNode in currNode.Parent.Nodes) { if (tmpNode.Checked) { checkedFlag = true; break; } } currNode.Parent.Checked = checkedFlag; SetParentNodeCheckedState(currNode.Parent, checkedFlag); } }