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,后期 ...
随机推荐
- CentOS 6.5 源码编译搭建LNMP(三台独立主机实现)
搭建前准备: 1.三台独立主机 nginx:192.168.1.102 php-fpm:192.168.1.105 mysql:192.168.1.103 2.相关软件的源码包 nginx:nginx ...
- vsftpd基于pam_mysql的虚拟用户机制
何为vsftpd? vsftpd:very secure ftp daemon 程序:/usr/sbin/vsftpd 配置文件:/etc/vsftpd/vsftpd.conf 其用户分为:匿名用户( ...
- 《Cracking the Coding Interview 》之 二叉树的创建 与 遍历(非递归+递归version)
#include <iostream> #include <cstdio> #include <vector> #include <stack> #de ...
- Codeforces Round #383 _python作死系列
A. Arpa's hard exam and Mehrdad's naive cheat 题意求1378的n次方的最后一位,懒的写循环节 瞎快速幂 py3 int和LL 合并为int了 def q_ ...
- linux或者windows下的文件拷贝
# 上代码 #!/usr/bin/env python # -*- coding:utf-8 -*- import os import shutil import tarfile base_dir ...
- flash项目优化总结
swc中的类如果没有在项目中没有被申明,在编译时就不会被编译进swf中,这样一些swc中的类和资源类如果不用了,只要不被声明就不会占用swf大小了.
- AngularJS学习---Routing(路由) & Multiple Views(多个视图) step 7
1.切换分支到step7,并启动项目 git checkout step- npm start 2.需求: 在步骤7之前,应用只给我们的用户提供了一个简单的界面(一张所有手机的列表),并且所有的模板代 ...
- c#开发Mongo笔记第九篇
用skip略过少量的文档还是不错的.但是要是数量非常多的话,skip就会变得很慢,因为要先找到需要被略过的数据,然后再抛弃这些数据.大多数数据库都会在索引中保存更多的元数据,用于处理skip, 但是m ...
- ios 上架需要注意的问题
前段时间上架产品的时候,因为定位提示问题被拒绝了,而且集成了融云及时聊天的key,没有从测试环境升级到生产环境,所以记录一下APP上架所需要注意的事项. 1.程序没有崩溃性BUG 2.程序不存在逻辑性 ...
- java byte[]生成
1. ByteArrayOutputStream extends OutputStream 提供了一个byte数组,和记录写入数组值个数的类. a.实现了write(int)这个抽象函数,这里默认只写 ...