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

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

我首先要说的就是数据库设计,要想动态加载成树形菜单,数据库表中就一定要设置父节点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. oc中的枚举定义

    typedef NS_ENUM(类型,枚举名){        枚举名+值名,       枚举名+值名,}; 该方法定义的枚举,OC会自动把其转换成合适当前版本的枚举.如果枚举值可合并的话 NS_E ...

  2. datagridview中使用checkbox问题。

    如果套用datagridview中的checkboxfield,生成的数据,会出现无法选择datagridview中数据项的问题,即checkbox不可以被鼠标点击,选中/取消选中.此checkbox ...

  3. Python验证码识别处理实例(转载)

    版权声明:本文为博主林炳文Evankaka原创文章,转载请注明出处http://blog.csdn.net/evankaka 一.准备工作与代码实例 1.PIL.pytesser.tesseract ...

  4. php中Closure::bind用法(手册记录)

    手册中 Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域. 具体参数可以看手册,这里记录下这个方法的实际用处. <?php trait MetaTrait { p ...

  5. $("<div />")代表的意思

    $("div")这个是匹配所有叫div的标签. $("<div />")表示生成一个div节点,但是div节点一般不通过这种方式,<div/& ...

  6. Java.web-application-development-environments-for-macosx

    Java Web Application开发 1 下载需要的软件 使用的软件并没有采用最新的版本,只是采用了次新版本. 1.1 下载Eclipse的jee版本 eclipse-jee-luna-SR2 ...

  7. DOM浏览器文档模型

    DOM浏览器文档模型 1.对XHM/XHTML 编写成DOM文档 可形成动态网页 2.'*'获取所有节点 GetElementsByTagName():获取所有的标签名的集合--需要在js中使用win ...

  8. 利用破解dll来获取到一个软件的注册码

    ---恢复内容开始--- 首先做这个事是纯属于个人研究而已,请勿以侵犯他人劳动成果. 今天看到了一个关于IL语句的文章,于是就学学,然后实践实践下.废话不多说了. 1.安装好某一个需要注册才可以的使用 ...

  9. sql like 查询

    查询 ids 含有 4  的  精确到4  54 不查询 select * from t_g_sku where ','||ids||',' like '%,4,%'; 序号 id mid quant ...

  10. 关于eclipse在线下载安装android SDK没反应解决方法

    虽然天朝将google这个服务器给和谐掉了 虽然我们也可以选择其他各类FQ软件 虽然你可能有其他手段解决 不过我还是要提供一个参考方法: 具体操作方式: 点击桌面左下角开始菜单中的搜索,把以下路径,复 ...