zoukankan      html  css  js  c++  java
  • winform Treeview控件使用

    做角色菜单权限时用到treeview控件做树状显示菜单,简单总结了一下用法:

    1.在winform窗体中拖入treeview控件,注意修改属性CheckBoxes属性为true,即在节点旁显示复选框

    2.后台动态加载数据库数据绑定到treeview上,子节点使用递归添加

    代码如下:

     1 //循环添加treeview节点
     2             for (int i = 0; i < dm.Rows.Count - 1; i++)//dm是数据库查出的数据表
     3             {
     4                 //添加父节点(一级菜单)
     5                 if (int.Parse(dm.Rows[i]["Menu_Type"].ToString()) == 0)
     6                 {
     7                     TreeNode pnode = new TreeNode();
     8                     pnode.Text = dm.Rows[i]["Menu_Text"].ToString();
     9                     pnode.Tag = int.Parse(dm.Rows[i]["Menu_ID"].ToString());
    10                     treeView1.Nodes.Add(pnode);
    11                     //调用方法,添加子级菜单
    12                     AddChildnode(int.Parse(dm.Rows[i]["Menu_ID"].ToString()), pnode);
    13                 }
    14             }

    添加子级菜单的方法如下:

     1 public void AddChildnode(int mid, TreeNode pnode)
     2         {
     3             RoleHandle rh = new RoleHandle();
     4             DataTable dm = rh.Menu_Texts_Type();
     5 
     6             for (int i = 0; i < dm.Rows.Count - 1; i++)
     7             {
     8                 if (int.Parse(dm.Rows[i]["Menu_Parent"].ToString()) == mid)
     9                 {
    10                     TreeNode cnode = new TreeNode();
    11                     cnode.Text = dm.Rows[i]["Menu_Text"].ToString();
    12                     cnode.Tag = int.Parse(dm.Rows[i]["Menu_ID"].ToString());
    13                     pnode.Nodes.Add(cnode);
    14                     //调用本方法,递归
    15                     AddChildnode(int.Parse(dm.Rows[i]["Menu_ID"].ToString()), cnode);
    16                 }
    17             }
    18         }

    3.获取角色对应的权限,有权限则勾选,没有权限则不管

    我同样封装了一个方法,方法代码如下:

     1          private void RoleChanged()
     2         {
     3             RoleHandle rh = new RoleHandle();
     4             int roleId = GetSelectedRoleId();
     5             //循环遍历treeview1所有根节点
     6             for (int i = 0; i < treeView1.Nodes.Count; i++)
     7             {
     8                     //查询数据库判断是否有该权限
     9                 if (rh.RoleMenuCheck(int.Parse(treeView1.Nodes[i].Tag.ToString()), roleId) != null && rh.RoleMenuCheck(int.Parse(treeView1.Nodes[i].Tag.ToString()), roleId).Rows.Count > 0)
    10                 {
    11                     //如果有权限,则勾选该节点
    12                     treeView1.Nodes[i].Checked = true;
    13                 }
    14                 else
    15                 {
    16                     treeView1.Nodes[i].Checked = false;
    17                 }
    18                  //调用递归的方法判断其子节点
    19                 TreeViewAllNodes(treeView1.Nodes[i], roleId);
    20             }
    21         }    

    判断子节点菜单是否有权限的方法(即判断子节点是否应勾选)

     1  private void TreeViewAllNodes(TreeNode parentNode, int roleId)
     2         {
     3             RoleHandle rh = new RoleHandle();
     4             foreach (TreeNode node in parentNode.Nodes)
     5             {
     6                 if (rh.RoleMenuCheck(int.Parse(node.Tag.ToString()), roleId) != null && rh.RoleMenuCheck(int.Parse(node.Tag.ToString()), roleId).Rows.Count > 0)
     7                 {
     8                     node.Checked = true;
     9                 }
    10                 else
    11                 {
    12                     node.Checked = false;
    13                 }
    14                 if (node.Nodes.Count > 0)//如果该节点下还有子节点
    15                 {
    16                     //运用递归,调用改方法
    17                     TreeViewAllNodes(node, roleId);
    18                 }
    19             }
    20         }

    4.使用鼠标单击treeview节点事件,实现点击某treeview节点时的子节点和父节点联动,代码如下:

     1 private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
     2          {
     3             //判断该节点状态(展开或折叠)
     4             if (nodestate)
     5             {
     6                 TreeNode node = e.Node;
     7                 if (node.Nodes.Count > 0)//包含子节点,实现子级联动
     8                 {
     9                      //实现子级联动的方法
    10                      SetTreeViewChecked(node);
    11                  }
    12                  if (node.Parent != null)//有父级菜单,实现父级联动
    13                  {
    14                     //实现父级联动的方法
    15                    SetParentNodeState(node);
    16                  }
    17                 nodestate = false;//修改节点状态
    18              }
    19          }

    子级联动的方法如下:

     1 private void SetTreeViewChecked(TreeNode node)
     2         {
     3             if (node == null)
     4             {
     5                 return;
     6             }
     7             if (node.Nodes.Count > 0)//判断该节点下有子节点
     8             {
     9                 foreach (TreeNode item in node.Nodes)
    10                 {
    11                     item.Checked = node.Checked;
    12                     //调用该方法,递归
    13                     SetTreeViewChecked(item);
    14                 }
    15             }
    16         }

    父级联动方法如下:

     1 private void SetParentNodeState(TreeNode node)
     2         {
     3             //定义变量用来设置父节点的选中情况,bool ck = false;假设子节点为全不选情况
     4             bool ck = false;
     5             TreeNode pn = node.Parent;
     6             if (pn != null)
     7             {
     8                 //假设所有子节点为全未选,循环判断是否有子节点选中
     9                 foreach (TreeNode item in pn.Nodes)
    10                 {
    11                     //如果有一个子节点是选中的,ck=true;
    12                     if (item.Checked)
    13                     {
    14                         ck = true;
    15                         break;
    16                     }
    17                 }
    18                 if (ck)
    19                 {
    20                     pn.Checked = true;
    21                 }
    22                 else
    23                 {
    24                     pn.Checked = false;
    25                     SetParentNodeState(pn);//递归
    26                 }
    27             }
    28         }

    补充说明一下,鼠标单击treeview节点事件有点坑,折叠或展开节点时也会触发该事件,所以我使用了TreeView1_AfterCheck事件解决了这个问题

     1 //设置全局变量,用来接收节点的状态 
     2 private bool nodestate = false;
     3         private void RoleMenuForm_Load(object sender, EventArgs e)
     4         {
     5          //在窗体加载事件中注册方法treeView1.AfterCheck
     6          treeView1.AfterCheck += TreeView1_AfterCheck;
     7         }
     8         //treeView1.AfterCheck方法
     9 
    10         private void TreeView1_AfterCheck(object sender, TreeViewEventArgs e)
    11         {
    12             //改变节点状态
    13             nodestate = true;
    14         }
  • 相关阅读:
    .net正在终止线程异常
    js判断客户浏览器类型,版本
    C#中ToString格式大全
    WPF TextBox 搜索框 自定义
    C#:获取设备电量相关信息
    C#中的委托与事件并存的理由
    WPF中的Pack URI
    SQLServer中的数据库备份和还原
    使用Aspose.Cells读取Excel
    SQLServer存储过程事务用法
  • 原文地址:https://www.cnblogs.com/Li232/p/10563915.html
Copyright © 2011-2022 走看看