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

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

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

代码如下:

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

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

 public void AddChildnode(int mid, TreeNode pnode)
{
RoleHandle rh = new RoleHandle();
DataTable dm = rh.Menu_Texts_Type(); for (int i = ; i < dm.Rows.Count - ; i++)
{
if (int.Parse(dm.Rows[i]["Menu_Parent"].ToString()) == mid)
{
TreeNode cnode = new TreeNode();
cnode.Text = dm.Rows[i]["Menu_Text"].ToString();
cnode.Tag = int.Parse(dm.Rows[i]["Menu_ID"].ToString());
pnode.Nodes.Add(cnode);
//调用本方法,递归
AddChildnode(int.Parse(dm.Rows[i]["Menu_ID"].ToString()), cnode);
}
}
}

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

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

          private void RoleChanged()
{
RoleHandle rh = new RoleHandle();
int roleId = GetSelectedRoleId();
//循环遍历treeview1所有根节点
for (int i = ; i < treeView1.Nodes.Count; i++)
{
//查询数据库判断是否有该权限
if (rh.RoleMenuCheck(int.Parse(treeView1.Nodes[i].Tag.ToString()), roleId) != null && rh.RoleMenuCheck(int.Parse(treeView1.Nodes[i].Tag.ToString()), roleId).Rows.Count > )
{
//如果有权限,则勾选该节点
treeView1.Nodes[i].Checked = true;
}
else
{
treeView1.Nodes[i].Checked = false;
}
//调用递归的方法判断其子节点
TreeViewAllNodes(treeView1.Nodes[i], roleId);
}
}

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

  private void TreeViewAllNodes(TreeNode parentNode, int roleId)
{
RoleHandle rh = new RoleHandle();
foreach (TreeNode node in parentNode.Nodes)
{
if (rh.RoleMenuCheck(int.Parse(node.Tag.ToString()), roleId) != null && rh.RoleMenuCheck(int.Parse(node.Tag.ToString()), roleId).Rows.Count > )
{
node.Checked = true;
}
else
{
node.Checked = false;
}
if (node.Nodes.Count > )//如果该节点下还有子节点
{
//运用递归,调用改方法
TreeViewAllNodes(node, roleId);
}
}
}

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

 private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
//判断该节点状态(展开或折叠)
if (nodestate)
{
TreeNode node = e.Node;
if (node.Nodes.Count > )//包含子节点,实现子级联动
{
//实现子级联动的方法
SetTreeViewChecked(node);
}
if (node.Parent != null)//有父级菜单,实现父级联动
{
//实现父级联动的方法
SetParentNodeState(node);
}
nodestate = false;//修改节点状态
}
}

子级联动的方法如下:

 private void SetTreeViewChecked(TreeNode node)
{
if (node == null)
{
return;
}
if (node.Nodes.Count > )//判断该节点下有子节点
{
foreach (TreeNode item in node.Nodes)
{
item.Checked = node.Checked;
//调用该方法,递归
SetTreeViewChecked(item);
}
}
}

父级联动方法如下:

 private void SetParentNodeState(TreeNode node)
{
//定义变量用来设置父节点的选中情况,bool ck = false;假设子节点为全不选情况
bool ck = false;
TreeNode pn = node.Parent;
if (pn != null)
{
//假设所有子节点为全未选,循环判断是否有子节点选中
foreach (TreeNode item in pn.Nodes)
{
//如果有一个子节点是选中的,ck=true;
if (item.Checked)
{
ck = true;
break;
}
}
if (ck)
{
pn.Checked = true;
}
else
{
pn.Checked = false;
SetParentNodeState(pn);//递归
}
}
}

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

 //设置全局变量,用来接收节点的状态
private bool nodestate = false;
private void RoleMenuForm_Load(object sender, EventArgs e)
{
//在窗体加载事件中注册方法treeView1.AfterCheck
treeView1.AfterCheck += TreeView1_AfterCheck;
}
//treeView1.AfterCheck方法 private void TreeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
//改变节点状态
nodestate = true;
}

winform Treeview控件使用的更多相关文章

  1. Winform TreeView控件技巧

    在开发的时候经常使用treeview控件来显示组织结构啊,目录结构啊,通常会结合属性checkedboxs,来做选中,取消的操作下面是一个选中,取消的小例子,选中节点的时候,如果节点存在子节点,可以选 ...

  2. Winform - TreeView控件,只展开根目录

    TreeNode类型是有Expand和ExpandAll这两个方法.而Treeview是只有ExpandAll的,想要展开根目录下面的节点的话 //只展开根目录 ) ].Expand();

  3. WinForm开发中针对TreeView控件改变当前选择节点的字体与颜色

    本文转载:http://www.cnblogs.com/umplatform/archive/2012/08/29/2660240.html 在B/S开发中,对TreeView控件要改变当前选中节点的 ...

  4. HTTP模拟工具【C#/Winform源码】、Json绑定TreeView控件、使用了MetroModernUI、RestSharp、Dapper.Net、Newtonsoft.Json、SmartThreadPool这几个主要开源框架

    HTTP模拟工具 开发语言:C#/Winform开发工具:Visual Studio 2017数据库:   SQLite使用框架:界面-MetroModernUI              Http请 ...

  5. Winform中Treeview控件失去焦点,将选择的节点设置为高亮显示 (2012-07-16 13:47:07)转载▼

    Winform中Treeview控件失去焦点,将选择的节点设置为高亮显示 (2012-07-16 13:47:07)转载▼标签: winform treeview drawnode Treeview控 ...

  6. C#Winform中treeView控件使用总结

    1.如何展开结点时改变图标(注意:不是选中时) 要在目录中使用图标首先要加入一个控件ImageList(命名为imageList1),然后可以按图片的index或名称引用图片. 然后需要在TreeVi ...

  7. C# TreeView 控件的综合使用方法

    1.概述 该篇文章开发使用的语言c#,环境visualstudio2010,sql数据库.主要内容包括: (1)treeView控件添加根节点.子节点的基本方法,节点的删除. (2)把treeView ...

  8. C#编程,TreeView控件的学习

    新建一个WinForm项目之后,在窗体中放入一个treeView控件(treeView1),根据数据库数据填充建立树节点.数据库的结构如下: ID        Title        P_ID a ...

  9. 如何:使用TreeView控件实现树结构显示及快速查询

    本文主要讲述如何通过使用TreeView控件来实现树结构的显示,以及树节点的快速查找功能.并针对通用树结构的数据结构存储进行一定的分析和设计.通过文本能够了解如何存储层次结构的数据库设计,如何快速使用 ...

随机推荐

  1. iDempiere 使用指南 测试 及 开发 虚拟机下载

    Created by 蓝色布鲁斯,QQ32876341,blog http://www.cnblogs.com/zzyan/ iDempiere官方中文wiki主页 http://wiki.idemp ...

  2. learn OpenStack by picture

  3. .NET开源工作流RoadFlow-表单设计-日期时间选择

    在表单中添加一个日期时间选择框: 选择范围:指定一个日期选择范围. 时间:是否允许选择时间.

  4. Android 环信(Android)设置头像和昵称的方法

    最近,经常有朋友问到,如何集成环信头像,怎么才能快速显示头像,因时间紧急,很多朋友都没有时间慢慢的研究代码,这里大家稍微花10分钟看一下文章,看完后再花5分钟改一下代码,即可达到你们所要的效果. 当然 ...

  5. CAA介绍(转)

    CAA是DS公司正对于其一系列产品,eg:CATIA,ENOVIA,DELIMA,etc,进行二次开发的一个环境.与VC结合的比较紧密.CAAV4是用于Unix/Linux的,到CAAV5才移植到Wi ...

  6. 最新一道面試題目,input: int[1,1,2,2,2,3,3,3],output [3,2,1],要求按照數字出現的次數從多到少排列元素。

    面試當時沒有及時答出來,感覺當時在面試官的提示下跑偏了.想用兩個數組來mapping key和value然後對等排序,但是因為面試官讓用Array.sort而沒想好有什麼好辦法,結果可想而知.但是題目 ...

  7. 再学UML-Bug管理系统UML2.0建模实例(二)

    2.3 BMS顺序图(需求模型)       在UML中,我们将顺序图分为两类,一类用于描述系统需求,构造系统的需求模型(分析模型):另一类用于指导设计与实现,构造系统的实现模型(设计模型).     ...

  8. 让免费版MarkdownPad2使用Pro版本的功能

    让免费版MarkdownPad2使用Pro版本的功能 找到配置文件 启用Markdown扩展模式 Markdown处理器:Github风格 语法检查设置 自动保存设置 找到配置文件 一般在用户的数据目 ...

  9. linux命令有用

    uptime 命令用来输出系统任务队列信息 last 列出目前与过去登入系统的用户相关信息 free 用来显示系统内存状态 ps 相應的選項組合為ps -ef.ps aux,可以通過這些組合準確定位系 ...

  10. extension Kingfisher where Base: Image:泛型类型的具体化与实例化

    具体化:针对特定的类型参量进行二次定义: 实例化:实例化: