天天看點

C# Winform TreeView父子節點選中狀态關聯

/// <summary>
        /// TreeView控件的選中後事件
        /// </summary>
        /// <param name="node"></param>
        private void treeView_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action != TreeViewAction.ByMouse)
                return;

            this.UpdateNodesCheckState(e.Node);
        }
        #region  節點關聯
        /// <summary>
        /// 設定節點上下級狀态
        /// </summary>
        /// <param name="node"></param>
        private void UpdateNodesCheckState(TreeNode node)
        {
            //設定子節點,向下遞歸
            SetChildNode(node);

            //設定父節點,向上遞歸
            if (node.Checked)
            {
                //勾選
                SetParentNodeChecked(node);
            }
            else
            {
                //未勾選
                SetParentNodeUnChecked(node);
            }
        }

        /// <summary>
        /// 節點勾選,設定父節點選中。并向上遞歸設定選中
        /// </summary>
        /// <param name="node"></param>
        private void SetParentNodeChecked(TreeNode node)
        {
            if (node.Parent != null)
            {
                int temp = 0;
                foreach (TreeNode brother in node.Parent.Nodes)
                {
                    if (brother.Checked == false)
                    {
                        temp--;
                    }
                    else
                    {
                        temp++;
                    }
                }
                if (temp == node.Parent.Nodes.Count)
                {
                    node.Parent.Checked = true;
                }
                SetParentNodeChecked(node.Parent);
            }
        }

        /// <summary>
        /// 節點未勾選,設定上級節點狀态
        /// 判斷同級節點狀态,設定父節點
        /// </summary>
        /// <param name="node"></param>
        private void SetParentNodeUnChecked(TreeNode node)
        {

            if (node.Parent != null)
            {
                int temp = 0;
                foreach (TreeNode brother in node.Parent.Nodes)
                {
                    if (brother.Checked == false)
                    {
                        temp++;
                    }
                   
                }
                if (temp > 0)
                {
                    node.Parent.Checked = false;
                }
                SetParentNodeUnChecked(node.Parent);
            }

           
        }
        /// <summary>
        /// 父節點變化,其子節點同步變化,其所有子節點與父節點勾選狀态保持一緻。
        /// </summary>
        /// <param name="node"></param>
        private void SetChildNode(TreeNode node)
        {
            foreach (TreeNode childNode in node.Nodes)
            {
                childNode.Checked = node.Checked;
                if (node.Nodes.Count > 0)
                    SetChildNode(childNode);
            }
        }

        #endregion