在做权限系统的时候,需要有一个树形的菜单。下图就是一个树形菜单的样式

但问题是,我们可以实现写死的树形菜单。什么是写死的?就是在前台代码中写好要加载的树形菜单是什么样子的。但是我们权限系统的要求是动态加载树形菜单,也就是根据数据库里面表的内容动态加载。

我首先要说的就是数据库设计,要想动态加载成树形菜单,数据库表中就一定要设置父节点ID和自身ID。通过父节点ID判断自身是属于哪一级菜单,而通过自身ID判断其对应的下一级菜单。这是数据库设计应该注意的地方,如果没有父节点和自身子节点,那么就没办法实现动态加载树形菜单。

动态加载树形菜单的实现利用的zTree。这里顺便提一下,zTree的网站做的真的很好,而且各种类型的zTree做的非常完美。我就是利用zTree来实现的,只不过与之不同的是zTree实现的树菜单也是在前台写好的,我们要做的就是将后台用数据库查询到的代码拼接成前台已经写好的代码格式。

这是前台写好的树菜单格式:

我们要做的就是将前台这种树形菜单格式在后台拼出来,而在树形菜单中显示的菜单名称是从数据库中查询出来的。最开始的时候尝试拼JSON串,但是事实证明,我失败了,拼出来的字符串运行的时候根本显示不出来

拼出的JSON串跟咱们要拼接的格式是不同的,JSON串拼接出来的格式适用于结构比较简单,这样利用循环可以将需要的字符串拼接出来。而我们需要的字符串是需要判断下一级是否有子节点的,这个利用JSON串我没有实现,只能实现一级菜单,而对应的实现三级菜单我没有拼出来。很遗憾,但是利用循环、遍历和DataTable的查询,最终实现了树形菜单字符串的拼接。下面是我实现的代码

这个对应的实现二级菜单的拼接

  1. public string getTree(string strTree)
  2. {
  3. string Chilstr = "";
  4. //获取DataTable
  5. zTreeBLL zTree = new zTreeBLL();
  6. DataTable dt = new DataTable();
  7. dt = zTree.QueryResource();
  8. //查询父节点有多少条不重复的数据
  9. zTreeBLL zTree1 = new zTreeBLL();
  10. DataTable dt1 = new DataTable();
  11. dt1 = zTree1.QueryParidNum();
  12. //父节点只能加到4
  13. //for (int p = 0; p < Convert.ToInt32(dt1.Rows[0][0]); p++)   //Convert.ToInt32强制转换字符,把Object类型转换成int
  14. //{
  15. int parentId = 0;
  16. //查找第一个父节点有多少个,即初值为0的父节点
  17. DataRow[] rowsP = dt.Select("ParentID=" + parentId);
  18. //利用循环将父节点拼接起来
  19. for (int i = 0; i < rowsP.Length; i++)
  20. {
  21. //把rowsP里面的数值取出来
  22. foreach (DataRow drP in rowsP)
  23. {
  24. string parName = drP["ResourceName"].ToString();
  25. //strTree = "[{name:\""+ parName + "\"";
  26. strTree = "[{name:\"" + parName + "\"";
  27. DataRow[] rowsC = dt.Select("ParentID=" + parentId + 1);
  28. if (rowsC.Length > 0)  //如果子节点不为0,则开始拼接子节点的字符串
  29. {
  30. //利用循环将父节点对应下的子节点串起来
  31. foreach (DataRow drC in rowsC)
  32. {
  33. string chilName = drC["ResourceName"].ToString();
  34. Chilstr = Chilstr + "{name:\"" + chilName + "\"}";
  35. Chilstr = Chilstr + ",";
  36. }
  37. Chilstr = Chilstr.Remove(Chilstr.LastIndexOf(","), 1);
  38. strTree = strTree + ",children:[" + Chilstr + "]}];";
  39. }
  40. else
  41. {
  42. strTree = strTree + "\"}];";
  43. }
  44. }
  45. }
  46. //    parentId++;
  47. //}
  48. return strTree;
  49. }

这个对应的是多级菜单的拼接

  1. public string getTree(string strTree)
  2. {
  3. string Chilstr = "";
  4. //获取DataTable
  5. zTreeBLL zTree = new zTreeBLL();
  6. DataTable dt = new DataTable();
  7. dt = zTree.QueryResource();
  8. //查询父节点有多少条不重复的数据
  9. zTreeBLL zTree1 = new zTreeBLL();
  10. DataTable dt1 = new DataTable();
  11. dt1 = zTree1.QueryParidNum();
  12. //父节点只能加到4
  13. //for (int p = 0; p < Convert.ToInt32(dt1.Rows[0][0]); p++)   //Convert.ToInt32强制转换字符,把Object类型转换成int
  14. //{
  15. int parentId = 0;
  16. //查找第一个父节点有多少个,即初值为0的父节点
  17. DataRow[] rowsP = dt.Select("ParentID=" + parentId);
  18. //利用循环将父节点拼接起来
  19. for (int i = 0; i < rowsP.Length; i++)
  20. {
  21. //把rowsP里面的数值取出来
  22. foreach (DataRow drP in rowsP)
  23. {
  24. string parName = drP["ResourceName"].ToString();
  25. //strTree = "[{name:\""+ parName + "\"";
  26. strTree = "[{name:\"" + parName + "\"";
  27. DataRow[] rowsC = dt.Select("ParentID=" + parentId + 1);
  28. if (rowsC.Length > 0)  //如果子节点不为0,则开始拼接子节点的字符串
  29. {
  30. //利用循环将父节点对应下的子节点串起来
  31. foreach (DataRow drC in rowsC)
  32. {
  33. string Threestr = "";
  34. //判断二级菜单下对应的ID,也就是查找三级菜单的ParentID
  35. string chilFollow = drC["ID"].ToString();
  36. //查询三级菜单
  37. DataRow[] rowsThree = dt.Select("ParentID=" + chilFollow);
  38. //判断是否存在三级菜单
  39. if (rowsThree.Length > 0)
  40. {
  41. foreach (DataRow drThree in rowsThree)
  42. {
  43. string ThreeName = drThree["ResourceName"].ToString();
  44. Threestr = Threestr + "{name:\""+ThreeName+"\"}";
  45. Threestr = Threestr + ",";
  46. }
  47. Threestr = Threestr.Remove(Threestr.LastIndexOf(","), 1);
  48. string chilName = drC["ResourceName"].ToString();
  49. Chilstr = Chilstr + "{name:\"" + chilName + "\",children:["+Threestr+"]},";
  50. }
  51. //如果不存在三级菜单的话直接加载二级菜单
  52. else
  53. {
  54. string chilName = drC["ResourceName"].ToString();
  55. Chilstr = Chilstr + "{name:\"" + chilName + "\"}";
  56. Chilstr = Chilstr + ",";
  57. }
  58. }
  59. Chilstr = Chilstr.Remove(Chilstr.LastIndexOf(","), 1);
  60. strTree = strTree + ",children:[" + Chilstr + "]}];";
  61. }
  62. else
  63. {
  64. strTree = strTree + "\"}];";
  65. }
  66. }
  67. }
  68. return strTree;
  69. }

最终实现的效果

其实实现这个例子的方法还有很多种,比如说递归。虽然JSON串没有拼接成功,但是我觉得JSON串是可以实现的。只是鉴于个人能力的缘故最终没有拼接成功。动态加载树形菜单终于实现的,但是还有很多需要改进的地方,比如如何将这个方法封装起来,以至于可以无限的调用没有缺陷等,这是下一步值得继续探讨的问题。

C#动态加载树菜单的更多相关文章

  1. ExtJS 创建动态加载树

    Ext 中导航树的创建有两种方式:1.首先将所有的数据读出来,然后绑定到前台页面.2.每点击一个节点展开后加载子节点.在数据量比较小的时候使用第一种方式加载的会快一些,然而当数据量比较大的时候,我还是 ...

  2. easyui_tree 复选框 动态加载树

    controller动态获取单位用户树 #region 下拉树菜单 /// <summary> /// 获取工作人员树菜单 /// </summary> /// <par ...

  3. dtree实现动态加载树形菜单,动态插入树形菜单

    1.导入  dtree文件    dtree.css   img文件夹   dtree.js 2. 建立对应 的数据库      1      父ID     name    id 3    建立连接 ...

  4. EasyUI Jquery 动态加载树,点击节点加载

    <script type="text/javascript"> $(function() { $(document).ready(function() { $.post ...

  5. jQuery 动态加载树

    本案例中用到了jquery的 tree插件,在本文的附件中可以下载 jsp代码: <%@ page language="java" import="java.uti ...

  6. Vue + Element UI 实现权限管理系统 前端篇(十):动态加载菜单

    动态加载菜单 之前我们的导航树都是写死在页面里的,而实际应用中是需要从后台服务器获取菜单数据之后动态生成的. 我们在这里就用上一篇准备好的数据格式Mock出模拟数据,然后动态生成我们的导航菜单. 接口 ...

  7. Vue + Element UI 实现权限管理系统(动态加载菜单)

    动态加载菜单 之前我们的导航树都是写死在页面里的,而实际应用中是需要从后台服务器获取菜单数据之后动态生成的. 我们在这里就用上一篇准备好的数据格式Mock出模拟数据,然后动态生成我们的导航菜单. 接口 ...

  8. C#遍历XML文件动态加载菜单

    通过遍历XML文件动态加载菜单,顺便利用WebBrowser控件实现一个简单的桌面浏览器 效果如下: 代码如下: XMLFile1.xml <?xml version="1.0&quo ...

  9. C#自定义控件、用户控件、动态加载菜单按钮

    一.效果图,动态加载5个菜单按钮: 二.实现方法 1.创建用户控件 2.在用户控件拖入toolStrip 3.进入用户控件的Lood事件,这里自动添加5个选  ToolStripMenuItem,后期 ...

随机推荐

  1. 当前JS文件中加入其他js文件

    注意:在html文件导入a.js时,应该把script></script写在/body>后面,否则 document.write()方法有问题. 在载入页面后,浏览器输出流自动关闭: ...

  2. iOS9的新特性以及适配方案

    新的iOS 9系统比iOS8更稳定,功能更全面,而且还更加开放.iOS 9加入了更多的新功能,包括更加智能的Siri,新加入的省电模式.iOS 9为开发者提供5000个全新的API. 1. 限制HTT ...

  3. iOS /* */多个嵌套解决

    解决办法 #if 0 /* */ #endif

  4. ios底层网络请求错误码

    kCFHostErrorHostNotFound = 1, kCFHostErrorUnknown = 2, // Query the kCFGetAddrInfoFailureKey to get ...

  5. java io学习之File类

    1.先看下四个静态变量 static String pathSeparator The system-dependent path-separator character, represented a ...

  6. zabbix网络发现

    zabbix的网络自动发现是一个非常强大的功能,该功能可以完成以下工作 •快速发现并添加主机. •简单的管理. •随着环境的改变而快速搭建监控系统. 网络发现基于以下信息 •ip地址段 •基于服务的F ...

  7. POJ 3686 The Windy's 最小费用最大流

    每个工厂拆成N个工厂,费用分别为1~N倍原费用. //#pragma comment(linker, "/STACK:1024000000,1024000000") #includ ...

  8. 11 个 Linux 上最佳的图形化 Git 客户端

    Git是软件开发和若干其他版本控制任务免费和开源的分布式版本控制系统.它被设计用来以应付一切从小到非常大的项目,基于速度,效率和数据完整性. Linux用户主要通过命令行管理Git,不过,一些图形用户 ...

  9. mongodb+pycharm使用报错,无法往mongodb存文件

    1 mongodb必须在启用状态下,启用如下 C:/mongodb/bin>mongod --dbpath C:\mongodb\data\db 不能关闭cmd 2 其他问题,貌似在Connec ...

  10. div中嵌套div水平垂直居中

    div中嵌套一个居中的div有很多方法,如果不想调整边距,有一个简单的方法: <div align="center" style="width: 200px;hei ...