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

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

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

    http://blog.jobbole.com/25944/ 1,概念 git服务器:就是一个仓储,一个大家都可以访问的公共仓储,大家可以从这个仓储中拉取和推送数据. 协议: 与gist服务通讯的仓储 ...

  2. [wechall] Time to Reset (Exploit, Coding, PHP)

    Time to Reset (Exploit, Coding, PHP) <?php $start=1453000000; $cstf="nipNlJ6ZQPuGQ3i90QUTP8J ...

  3. Tornado 异步客户端

    前言 Tornado是很优秀的非阻塞式服务器,我们一般用它来写Web 服务器,据说知乎就是用Tornado写的. 如果对tornado源码不是很了解,可以先看一下另一篇文章: http://yunji ...

  4. Angularjs学习---angularjs环境搭建,ubuntu 12.04下安装nodejs、npm和karma

    1.下载angularjs 进入其官网下载:https://angularjs.org/‎,建议下载最新版的:https://ajax.googleapis.com/ajax/libs/angular ...

  5. 【golang】go语言,进行并发请求的wrap变参封装

    package main import ( "fmt" "sync" "time" ) type WaitGroupWrapper stru ...

  6. LaTex学习笔记(一):review

    1.百分号 \% 2.下标 b_{ij} 3.表格(excel2latex) 符号说明 \begin{table}[H] \centering \begin{tabular}{m{100pt}< ...

  7. 按enter执行click或者搜索问题

    最近需要将按按钮搜索的功能,改为支持按enter回车键,搜索. 实现按enter,执行click事件还是比较简单的. //按回车搜索用户 $(window).keydown(function (eve ...

  8. 【Map】MapTest

    package cn.itcast.p1.map.test; import java.util.HashMap; import java.util.Map; public class MapTest2 ...

  9. 递推 N循环问题

    Description   我们知道,在编程中,我们时常需要考虑到时间复杂度,特别是对于循环的部分.例如, 如果代码中出现 for(i=1;i<=n;i++) OP ; 那么做了n次OP运算,如 ...

  10. WPF RichTextBox,关键字搜索,样式改变,超链接替换,图文混排

    RichTextBox 只是一个控件,表示对 FlowDocument 对象执行操作的丰富编辑控件.它所承载的内容由其 Document 属性来呈现. Document 是一个 FlowDocumen ...