WinForm TreeView的一點用法


TreeView一般都包含父節點和子節點,常規情況下有以下幾種情況:
1.選中父節點之后,該父節點下面的所有子節點都被選中,取消選擇父節點,則該父節點下面所有的子節點全部跟着取消選擇。

2.如果某一個父節點下面有任何一個子節點被選中,那么該父節點也是處於選中狀態。

3.如果某一個父節點下面最后一個處於選中的子節點被取消選中的話(這句話貌似有點繞口),該父節點也要處於取消選中的狀態。

4.頁面首先將所有的數據加載到TreeView上面,然后TreeView根據不同的情況做出相應的調整,比如選擇Admin組別的時候勾選所有的選項,勾選User組別的時候僅僅勾選允許登錄的選項。

前面3種情況可以如下解決:

private bool m_SetClick = true;
        
        private void SetSubNodeCheck(TreeNode p_TreeNode, bool p_SelectCheck)
        {
            m_SetClick = false;
            foreach (TreeNode _SubNode in p_TreeNode.Nodes)
            {
                _SubNode.Checked = p_SelectCheck;
                SetSubNodeCheck(_SubNode, p_SelectCheck);
            }

        }
        private void SetParentCheck(TreeNode p_TreeNode)
        {
            if (p_TreeNode.Checked && p_TreeNode.Parent != null)
            {
                p_TreeNode.Parent.Checked = true;
                SetParentCheck(p_TreeNode.Parent);
            }
        }
        private void SetParentNotCheck(TreeNode p_TreeNode)
        {
            if (!p_TreeNode.Checked && p_TreeNode.Parent != null)
            {
                foreach (TreeNode _Node in p_TreeNode.Parent.Nodes)
                {
                    if (_Node.Checked) return;
                }
                p_TreeNode.Parent.Checked = false;
                SetParentNotCheck(p_TreeNode.Parent);
            }
        }

然后在AfterCheck里面增加如下代碼:

private void tvFunction_AfterCheck(object sender, TreeViewEventArgs e)
        {
            // 禁用TreeView視圖重繪的功能。
            tvFunction.BeginUpdate();
            if (m_SetClick)
            {
                SetSubNodeCheck(e.Node, e.Node.Checked);
                SetParentCheck(e.Node);
                SetParentNotCheck(e.Node);
                m_SetClick = true;
            }
            // 啟用TreeView視圖重繪的功能。
            tvFunction.EndUpdate();
        }

關於第4個問題,我遇到的情況是這樣的,在權限設置里面我想在窗體Load的時候將所有的菜單組以及對應的子菜單都加載到樹上面來,當我點擊不同的角色的時候自動顯示對應的權限,比如,我點擊Administrator”,則TreeView上面的所有菜單組以及子菜單全部都勾選上,如果我點擊“普通用戶”,則那些系統設置相關的內容都不勾選,這就是需求,下面我們來看看如何實現這個需求:
首先,我根據不同的角色返回了一張表或者是一個集合,當用戶點擊角色名稱的時候就已經獲取到了這個表或者集合,我們要做的就是匹配界面上面TreeView里面的所有節點和返回來的那一張Table或者集合,如果能夠完全匹配,那么就將其Checked屬性設置為True,否則不理它,這里用到了遞歸來遍歷這棵樹,遞歸代碼如下:

/// <summary>
        /// 遞歸遍歷TreeView,然后對比已有的數據和TreeView上面的節點數據,
        /// 如果匹配成功,則選中TreeView上面的相應節點。
        /// </summary>
        /// <param name="tn"></param>
        private void FindTreeView(TreeNode tn)
        {
            tn.Checked = false;
            string FunctionID_dt = string.Empty;
            string FunctionID_tv = string.Empty;
            for (int i = 0; i < dt_ExistsRole.Rows.Count; i++)
            {
                FunctionID_dt = dt_ExistsRole.Rows[i][1].ToString().Trim();
                FunctionID_tv = tn.Name.Trim();
                if (FunctionID_dt == FunctionID_tv)
                {
                    tn.Checked = true;
                }
            }
            foreach (TreeNode tnSub in tn.Nodes)
            {
                FindTreeView(tnSub);
            }
        }

在TreeView的AfterSelect事件里面調用它,一定要是AfterSelect里面,而不是Click里面:

private void tvUserGroup_AfterSelect(object sender, TreeViewEventArgs e)
        {
            //每次選擇一個節點的時候都取到這個節點的名稱,名稱就是數據庫里面的UserGroupID。
            dt_ExistsRole = new BLL.sys_SetRoleManager().GetExistsRole("1", tvUserGroup.SelectedNode.Name);

            foreach (TreeNode tn in tvFunction.Nodes)
            {
                FindTreeView(tn);
            }
        }

效果如下圖所示:


免責聲明!

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



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