C#动态加载树菜单
在做权限系统的时候,需要有一个树形的菜单。下图就是一个树形菜单的样式
但问题是,我们可以实现写死的树形菜单。什么是写死的?就是在前台代码中写好要加载的树形菜单是什么样子的。但是我们权限系统的要求是动态加载树形菜单,也就是根据数据库里面表的内容动态加载。
我首先要说的就是数据库设计,要想动态加载成树形菜单,数据库表中就一定要设置父节点ID和自身ID。通过父节点ID判断自身是属于哪一级菜单,而通过自身ID判断其对应的下一级菜单。这是数据库设计应该注意的地方,如果没有父节点和自身子节点,那么就没办法实现动态加载树形菜单。
动态加载树形菜单的实现利用的zTree。这里顺便提一下,zTree的网站做的真的很好,而且各种类型的zTree做的非常完美。我就是利用zTree来实现的,只不过与之不同的是zTree实现的树菜单也是在前台写好的,我们要做的就是将后台用数据库查询到的代码拼接成前台已经写好的代码格式。
这是前台写好的树菜单格式:
我们要做的就是将前台这种树形菜单格式在后台拼出来,而在树形菜单中显示的菜单名称是从数据库中查询出来的。最开始的时候尝试拼JSON串,但是事实证明,我失败了,拼出来的字符串运行的时候根本显示不出来
拼出的JSON串跟咱们要拼接的格式是不同的,JSON串拼接出来的格式适用于结构比较简单,这样利用循环可以将需要的字符串拼接出来。而我们需要的字符串是需要判断下一级是否有子节点的,这个利用JSON串我没有实现,只能实现一级菜单,而对应的实现三级菜单我没有拼出来。很遗憾,但是利用循环、遍历和DataTable的查询,最终实现了树形菜单字符串的拼接。下面是我实现的代码
这个对应的实现二级菜单的拼接
- public string getTree(string strTree)
- {
- string Chilstr = "";
- //获取DataTable
- zTreeBLL zTree = new zTreeBLL();
- DataTable dt = new DataTable();
- dt = zTree.QueryResource();
- //查询父节点有多少条不重复的数据
- zTreeBLL zTree1 = new zTreeBLL();
- DataTable dt1 = new DataTable();
- dt1 = zTree1.QueryParidNum();
- //父节点只能加到4
- //for (int p = 0; p < Convert.ToInt32(dt1.Rows[0][0]); p++) //Convert.ToInt32强制转换字符,把Object类型转换成int
- //{
- int parentId = 0;
- //查找第一个父节点有多少个,即初值为0的父节点
- DataRow[] rowsP = dt.Select("ParentID=" + parentId);
- //利用循环将父节点拼接起来
- for (int i = 0; i < rowsP.Length; i++)
- {
- //把rowsP里面的数值取出来
- foreach (DataRow drP in rowsP)
- {
- string parName = drP["ResourceName"].ToString();
- //strTree = "[{name:\""+ parName + "\"";
- strTree = "[{name:\"" + parName + "\"";
- DataRow[] rowsC = dt.Select("ParentID=" + parentId + 1);
- if (rowsC.Length > 0) //如果子节点不为0,则开始拼接子节点的字符串
- {
- //利用循环将父节点对应下的子节点串起来
- foreach (DataRow drC in rowsC)
- {
- string chilName = drC["ResourceName"].ToString();
- Chilstr = Chilstr + "{name:\"" + chilName + "\"}";
- Chilstr = Chilstr + ",";
- }
- Chilstr = Chilstr.Remove(Chilstr.LastIndexOf(","), 1);
- strTree = strTree + ",children:[" + Chilstr + "]}];";
- }
- else
- {
- strTree = strTree + "\"}];";
- }
- }
- }
- // parentId++;
- //}
- return strTree;
- }
这个对应的是多级菜单的拼接
- public string getTree(string strTree)
- {
- string Chilstr = "";
- //获取DataTable
- zTreeBLL zTree = new zTreeBLL();
- DataTable dt = new DataTable();
- dt = zTree.QueryResource();
- //查询父节点有多少条不重复的数据
- zTreeBLL zTree1 = new zTreeBLL();
- DataTable dt1 = new DataTable();
- dt1 = zTree1.QueryParidNum();
- //父节点只能加到4
- //for (int p = 0; p < Convert.ToInt32(dt1.Rows[0][0]); p++) //Convert.ToInt32强制转换字符,把Object类型转换成int
- //{
- int parentId = 0;
- //查找第一个父节点有多少个,即初值为0的父节点
- DataRow[] rowsP = dt.Select("ParentID=" + parentId);
- //利用循环将父节点拼接起来
- for (int i = 0; i < rowsP.Length; i++)
- {
- //把rowsP里面的数值取出来
- foreach (DataRow drP in rowsP)
- {
- string parName = drP["ResourceName"].ToString();
- //strTree = "[{name:\""+ parName + "\"";
- strTree = "[{name:\"" + parName + "\"";
- DataRow[] rowsC = dt.Select("ParentID=" + parentId + 1);
- if (rowsC.Length > 0) //如果子节点不为0,则开始拼接子节点的字符串
- {
- //利用循环将父节点对应下的子节点串起来
- foreach (DataRow drC in rowsC)
- {
- string Threestr = "";
- //判断二级菜单下对应的ID,也就是查找三级菜单的ParentID
- string chilFollow = drC["ID"].ToString();
- //查询三级菜单
- DataRow[] rowsThree = dt.Select("ParentID=" + chilFollow);
- //判断是否存在三级菜单
- if (rowsThree.Length > 0)
- {
- foreach (DataRow drThree in rowsThree)
- {
- string ThreeName = drThree["ResourceName"].ToString();
- Threestr = Threestr + "{name:\""+ThreeName+"\"}";
- Threestr = Threestr + ",";
- }
- Threestr = Threestr.Remove(Threestr.LastIndexOf(","), 1);
- string chilName = drC["ResourceName"].ToString();
- Chilstr = Chilstr + "{name:\"" + chilName + "\",children:["+Threestr+"]},";
- }
- //如果不存在三级菜单的话直接加载二级菜单
- else
- {
- string chilName = drC["ResourceName"].ToString();
- Chilstr = Chilstr + "{name:\"" + chilName + "\"}";
- Chilstr = Chilstr + ",";
- }
- }
- Chilstr = Chilstr.Remove(Chilstr.LastIndexOf(","), 1);
- strTree = strTree + ",children:[" + Chilstr + "]}];";
- }
- else
- {
- strTree = strTree + "\"}];";
- }
- }
- }
- return strTree;
- }
最终实现的效果
其实实现这个例子的方法还有很多种,比如说递归。虽然JSON串没有拼接成功,但是我觉得JSON串是可以实现的。只是鉴于个人能力的缘故最终没有拼接成功。动态加载树形菜单终于实现的,但是还有很多需要改进的地方,比如如何将这个方法封装起来,以至于可以无限的调用没有缺陷等,这是下一步值得继续探讨的问题。
C#动态加载树菜单的更多相关文章
- ExtJS 创建动态加载树
Ext 中导航树的创建有两种方式:1.首先将所有的数据读出来,然后绑定到前台页面.2.每点击一个节点展开后加载子节点.在数据量比较小的时候使用第一种方式加载的会快一些,然而当数据量比较大的时候,我还是 ...
- easyui_tree 复选框 动态加载树
controller动态获取单位用户树 #region 下拉树菜单 /// <summary> /// 获取工作人员树菜单 /// </summary> /// <par ...
- dtree实现动态加载树形菜单,动态插入树形菜单
1.导入 dtree文件 dtree.css img文件夹 dtree.js 2. 建立对应 的数据库 1 父ID name id 3 建立连接 ...
- EasyUI Jquery 动态加载树,点击节点加载
<script type="text/javascript"> $(function() { $(document).ready(function() { $.post ...
- jQuery 动态加载树
本案例中用到了jquery的 tree插件,在本文的附件中可以下载 jsp代码: <%@ page language="java" import="java.uti ...
- Vue + Element UI 实现权限管理系统 前端篇(十):动态加载菜单
动态加载菜单 之前我们的导航树都是写死在页面里的,而实际应用中是需要从后台服务器获取菜单数据之后动态生成的. 我们在这里就用上一篇准备好的数据格式Mock出模拟数据,然后动态生成我们的导航菜单. 接口 ...
- Vue + Element UI 实现权限管理系统(动态加载菜单)
动态加载菜单 之前我们的导航树都是写死在页面里的,而实际应用中是需要从后台服务器获取菜单数据之后动态生成的. 我们在这里就用上一篇准备好的数据格式Mock出模拟数据,然后动态生成我们的导航菜单. 接口 ...
- C#遍历XML文件动态加载菜单
通过遍历XML文件动态加载菜单,顺便利用WebBrowser控件实现一个简单的桌面浏览器 效果如下: 代码如下: XMLFile1.xml <?xml version="1.0&quo ...
- C#自定义控件、用户控件、动态加载菜单按钮
一.效果图,动态加载5个菜单按钮: 二.实现方法 1.创建用户控件 2.在用户控件拖入toolStrip 3.进入用户控件的Lood事件,这里自动添加5个选 ToolStripMenuItem,后期 ...
随机推荐
- Ubuntu下shell脚本运行异常:bash和dash的区别
Ubuntu下我用bash到语法写了一个shell脚本(准确的说是把书上的脚本敲进电脑),在ubuntu下,用sh test.sh来运行,但是出现了意料之外到结果,比如echo -e "\n ...
- delphi项目中的modelsupport文件夹
delphi项目中的modelsupport文件夹 今天写着写着突然发现多了一个这个文件夹..苦思不得其解 看着又难受 删了又重建 终于找到了 存此备查;Tools--option--toget ...
- iOS9的新特性以及适配方案
新的iOS 9系统比iOS8更稳定,功能更全面,而且还更加开放.iOS 9加入了更多的新功能,包括更加智能的Siri,新加入的省电模式.iOS 9为开发者提供5000个全新的API. 1. 限制HTT ...
- P2001xor-sigma 字典树,然而好坑
https://vijos.org/p/2001 设perXor[i]表示1---i的前缀异或值. 那么要得到某一段的异或值,只需要perXor[j] ^ perXor[i - 1] 那么我们把per ...
- JS打印页面
打印 整个html页面(PS:样式要写在页面里面才能打印(就是用内部样式)) <a id="dayi" runat="server ...
- 第二节 初识 python
Python的由来 在1989年12月时,吉多·范罗苏姆——龟叔,想寻找一门“课余”编程项目来打发圣诞节前后的时间.Guido决定为当时正构思的一个新的脚本语言写一个解释器,它是ABC语言(教学语言. ...
- ajax无刷新上传图片
页面: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> & ...
- linux下mysql集群的安装
3台redhat服务器: SQL节点(mysqld): 192.168.1.77;192.168.1.78 数据节点(ndbd): 192.168.1.77;192.168.1.78 管理节点(ndb ...
- String与StringBuffer的区别
首先,String和StringBuffer主要有2个区别: (1)String类对象为不可变对象,一旦你修改了String对象的值,隐性重新创建了一个新的对象,释放原String对象,StringB ...
- Java关键字:transient,strictfp和volatile简介
关键字:transient 使用对象:字段 介绍:transient说明一个属性是临时的,不会被序列化. 当对象进行序列化(Serializable)过程时候,有一些属性的状态是瞬时的,这样的对象是无 ...