c# TreeView實現三種選中狀態


c# 項目中需要實現樹狀選項的勾選,有全選,半勾選,不選的狀態。

因原控件中只有勾選和不勾選兩種狀態,所以半勾選狀態需要使用代碼繪制和自行定義。

勾選:Node.Checked=true

不勾選: Node.Checked=false

半勾選: Node.Checked=false && Node.ToolTipText="部分勾選"

注意:半勾選狀態需要重新繪制控件需要設置控件屬性DrawMode為OwnerDrawText或者OwnerDrawAll

核心邏輯一:設置父親節點的選中狀態(選中一個節點時,判斷兄弟節點是否全選;取消一個節點時,需要判斷兄弟節點是否有選中狀態和半選中狀態。由此來判斷父節點的選中狀態)

 //取消節點選中狀態之后,取消所有父節點的選中狀態
        private void setParentNodeCheckedState(TreeNode currNode, bool state)
        {
            TreeNode parentNode = currNode.Parent; //獲得當前節點的父節點
            parentNode.Checked = state; //設置父節點的選中狀態 if (state == false) //當狀態設置為false 
            {
                int flag = 0;
                foreach (TreeNode broNode in parentNode.Nodes) //判斷該父節點的子節點中,是否有半勾選狀態的選項
                {
                    if (broNode.Checked||broNode.ToolTipText.Equals("部分勾選"))
                    {
                        flag = 1;
                    }
                }
                if (flag == 1) // 有設置父節點為半勾選狀態
                {
                    parentNode.ToolTipText = "部分勾選";
                    parentNode.Checked = false;
                }
                else  
                {   //設置父節點狀態為 未勾選
                    parentNode.ToolTipText = "";
                    parentNode.Checked = true;
                    parentNode.Checked = false;  //需要改變節點的Checked狀態,才能重新繪制控件;
                }
            }
            else {   //當父節點設置為選中狀態時 int flag = 0;
                foreach (TreeNode broNode in parentNode.Nodes)//判斷該父節點的子節點下是否有未選中的節點。
                {
                    if (!broNode.Checked)
                    {
                        flag = 1;
                    }
                }
                if (flag == 1)
                {
                    parentNode.ToolTipText = "部分勾選";
                    parentNode.Checked = false;
                }
                else
                {
                    parentNode.ToolTipText = "";
                    parentNode.Checked = true;
                }
            }
            if (currNode.Parent.Parent != null) //如果父節點之上還有父節點
            {  
                setParentNodeCheckedState(currNode.Parent, state); //遞歸調用
            }
        }

核心邏輯二:設置子節點的選中狀態

 //選中節點之后,選中節點的所有子節點
        private void setChildNodeCheckedState(TreeNode currNode, bool state)
        {
            TreeNodeCollection nodes = currNode.Nodes; //獲取所有子節點 if (nodes.Count > 0) //存在子節點 foreach (TreeNode tn in nodes) 
                {
                    tn.Checked = state;
                    tn.ToolTipText = "";
                    setChildNodeCheckedState(tn, state);//遞歸調用子節點的子節點
                }
        }

設置控件監聽屬性AfterCheck

  private void skinTreeView1_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action == TreeViewAction.ByMouse) //鼠標點擊
            {
                //textBox1.Text = e.Node.Text;
                if (e.Node.Checked) //選中
                {                    e.Node.ToolTipText = "";
                    //選中節點之后,選中節點的所有子節點
                    setChildNodeCheckedState(e.Node, true);
                    if (e.Node.Parent != null)
                    {
                        setParentNodeCheckedState(e.Node, true);
                    }
                }  
                else  //取消選中
                {
                    e.Node.ToolTipText = "";
                    //取消節點選中狀態之后,取消所有子節點的選中狀態
                    setChildNodeCheckedState(e.Node, false);
                    //如果節點存在父節點,取消父節點的選中狀態
                    if (e.Node.Parent != null)
                    {
                        setParentNodeCheckedState(e.Node, false);
                    }
                }
            }
        }

設置重新繪制監聽DrawNode,為半勾選狀態繪制新圖案

  private void ClassTreeList_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            if (e.Bounds.Location.X <= 0)
            {
                return;
            }
            var treeview = sender as TreeView;
            var brush = Brushes.Black; //黑色 if (e.Node.ToolTipText.EndsWith("部分勾選")&&e.Node.Checked==false)
            {  //判斷為半勾選狀態 var location = e.Node.Bounds.Location;
                location.Offset(-10, 7);
                var size = new Size(7, 7);
                e.Graphics.FillRectangle(brush, new Rectangle(location, size)); //這里繪制的是正方形
            }
            //繪制文本
            e.Graphics.DrawString(e.Node.Text, treeview.Font, brush, e.Bounds.Left, e.Bounds.Top);
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM