首先事件選擇,選擇的是MouseUp事件。爲啥?由於凡是跟Check有關的,在選中父節點或者子節點,都會二次觸發。而後發生的就是死循環。node
Up事件就能夠避免二次觸發。Down事件呢?那就觸發AfterCheck事件了。事件選好了, 直接上代碼。spa
處理思路:選中/取消當前節點,先選中其全部父節點,再選中其子節點code
注意平級節點處理:有平級節點選中,取消時須要遍歷父節點。blog
如有一個平級節點處於選中,則父節點爲選中。事件
若全部平級都沒有選中的了,則父節點要取消選中class
/// <summary> /// 處理樹節點選中和取消選中 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public static void treeView_MouseUpClick(object sender,MouseEventArgs e) { TreeView tree = sender as TreeView; if (tree == null) return; TreeNode node = tree.GetNodeAt(e.X, e.Y); if (node == null) return; SetTreeNodeCheckBoxState(node,true,node.Checked); SetTreeNodeCheckBoxState(node, false, node.Checked); } /// <summary> /// 處理父節點,子節點的選中 /// </summary> /// <param name="node">須要選中的樹</param> /// <param name="isSetParentState">是否選中父節點</param> /// <param name="state">選中/不選中</param> public static void SetTreeNodeCheckBoxState(TreeNode node, bool isSetParentState, bool state) { if (node == null) return; node.Checked = state; if (isSetParentState && node.Parent != null && node.Checked==true) { SetTreeNodeCheckBoxState(node.Parent, isSetParentState, state); } else if (isSetParentState && node.Parent != null && node.Checked == false) { //處理取消選中 bool isSelect = false; foreach(TreeNode n in node.Parent.Nodes) { if (n.Checked==true) isSelect = true; } //平級都未有選中的才取消選中 if(isSelect==false) SetTreeNodeCheckBoxState(node.Parent, isSetParentState, state); } else if (!isSetParentState && node.Nodes!=null && node.Nodes.Count > 0) { foreach (TreeNode node2 in node.Nodes) { SetTreeNodeCheckBoxState(node2, isSetParentState, state); } } }