本文轉載:http://www.cnblogs.com/luxiaoxun/p/3288003.html
很不錯的文章:http://www.cnblogs.com/allen0118/archive/2012/11/28/2793037.html
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);
}
}
{
// 通過鼠標或者鍵盤觸發事件,防止修改節點的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);
}
}