类似于多层级的角色与权限控制功能,用MVC实现MVC树控件,mvc中应用treeview,实现复选框树的多层级表单控件。最近我们的项目中需要用到树型菜单,以前使用WebForm时,树型菜单有微软提供的控件,非常方便,但现在需要在asp.netmvc中使用树形菜单,先说明下我们对树形菜单的需求:

1,支持CheckBox,允许对菜单项进行选择;
2,当选择父菜单时,它下面的子菜单全部选中;
3,当取消父菜单的选中状态时,下面的子菜单也全部取消;
4,比较方便的与MVC结合;

5,能够初始化选中状态。

6,能够以提交表单的方式,一次性将树绑定到后台接收的对象。

首先菜单数据对象:

完整的 CheckboxTreeHelper.cs 代码:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Text; /*
author:熊学浩
time:2016年6月5日
description:树形菜单控件(有问题请致信:xiongzaiqiren@163.com),或者请参考【http://www.cnblogs.com/xiongzaiqiren/】
*/
namespace System.Web.Mvc
{
/// <summary>
/// 菜单数据对象
/// </summary>
public class CheckboxTreeItem
{
/// <summary>
/// 显示的文本
/// </summary>
public string Text { get; set; }
/// <summary>
/// 显示文本对应的值
/// </summary>
public string Value { get; set; }
/// <summary>
/// 是否被选中
/// </summary>
public bool Checked { get; set; }
/// <summary>
/// 结合表单的辅助属性,View上使用(注意每个层级的索引必需从0开始并且是连续的)
/// </summary>
public string Index { get; set; } /// <summary>
/// 子菜单集合
/// </summary>
public IList<CheckboxTreeItem> Items { get; set; }
} /// <summary>
/// 复选框树控件
/// 熊学浩
/// 2016年6月3日
/// </summary>
public static class CheckboxTreeHelper
{
private static bool baselayer; public static String CheckboxTree(this HtmlHelper helper, string Name, CheckboxTreeItem Model, out string this_HtmlDomName, bool isChildNode = false)
{
if (null == Model)
{
this_HtmlDomName = string.Empty;
return string.Empty;
} StringBuilder sb = new StringBuilder();
if (!baselayer)
sb.Append("<div class=\"CheckboxTree\">"); if (!isChildNode)
sb.Append("<ul class=\"CBT-ul\">");
sb.Append("<li class=\"CBT-li\">"); this_HtmlDomName = Name + "[" + Model.Index + "]"; sb.Append("<label style=\"cursor:pointer;\">");
sb.AppendFormat("<input type=\"checkbox\" onchange=\"setCheckboxTreeItemValue(this);\" name=\"{0}\" value=\"{1}\" />", (this_HtmlDomName + ".Checked"), Model.Checked.ToString());
sb.AppendFormat("<span>{0}</span>", Model.Text);
sb.Append("</label>"); sb.AppendFormat("<input type=\"hidden\" name =\"{0}\" value=\"{1}\" />", (this_HtmlDomName + ".Text"), Model.Text);
sb.AppendFormat("<input type=\"hidden\" name =\"{0}\" value=\"{1}\" />", (this_HtmlDomName + ".Value"), Model.Value);
sb.AppendFormat("<input type=\"hidden\" name =\"{0}\" value=\"{1}\" />", (this_HtmlDomName + ".Index"), Model.Index); if (null != Model.Items)
{
sb.Append("<ul class=\"CBT-ul\">");
for (var i = ; i < Model.Items.Count; i++)
{
string _this_HtmlDomName;
sb.Append(CheckboxTree(helper, this_HtmlDomName + ".Items", Model.Items[i], out _this_HtmlDomName, true));
}
sb.Append("</ul>");
} sb.Append("</li>");
if (!isChildNode)
sb.Append("</ul>"); if (!baselayer)
sb.Append("</div>"); return sb.ToString();
}
public static String CheckboxTree(this HtmlHelper helper, string Name, IList<CheckboxTreeItem> Models)
{
if (null == Models) return string.Empty;
if (Models.Count > )
baselayer = true; StringBuilder sb = new StringBuilder();
if (baselayer)
sb.Append("<div class=\"CheckboxTree\">");
sb.Append("<ul class=\"CBT-ul\">"); string _this_HtmlDomName; foreach (CheckboxTreeItem item in Models)
{
sb.Append(CheckboxTree(helper, Name, item, out _this_HtmlDomName, true));
} sb.Append("</ul>");
if (baselayer)
sb.Append("</div>"); return sb.ToString();
}
}
}

字段说明:
Text:用于显示的文本,比如:总裁
Value:显示文本对应的ID,比如:0
Index:这个是结合表单的辅助属性,View上使用(注意每个层级的索引必需从0开始并且是连续的)
Checked:当前菜单项是否被选中,用户提交表单后我们可以通过这个属性判断用户的选择项
Items:当前菜单下的子菜单集合

树形菜单的输出:

 @model List<CheckboxTreeItem>

 @using (Html.BeginForm("test", "Home", new { }, FormMethod.Post, new { id = "form", name = "form" }))
{
@Html.AntiForgeryToken(); <link type="text/css" rel="stylesheet" href="@Url.Content("~/Models/CheckboxTree.css")" />
@Html.Raw(Html.CheckboxTree("CheckboxTree", Model)) @*这里是输出显示树形菜单*@
<script src="@Url.Content("~/Models/CheckboxTree.js")" type="text/javascript"></script>
}

无论是ajax还是直接post表单,最终的目的都是接收View中的数据,要想传递比较复杂的数据类型,我们需要对ASP.NET MVC Model Binding 有一定了解,之前也讲解过MyTreeViewItem的结果,有普通的数据类型,比如 string,bool,也是对象类型,比如MyTreeViewItem类型的Parent,也是基于集合的属性IList<MyTreeViewItem>,要想让表单中的数据直接传递给Controller,我们需要对表单元素的name进行特殊处理才行。

Controller:这是最重要的就是接收参数,它是一个List类型,无论菜单项有多少层,都会按树形数据结构层次组织好,方便我们查询。

 public ActionResult test(int id = )
{
ViewBag.IsEdit = id == ? false : true; List<CheckboxTreeItem> cb = new List<CheckboxTreeItem>() {
new CheckboxTreeItem() { Value="A", Text="一级A", Index="" },
new CheckboxTreeItem() { Value="B", Text="一级B", Index="" },
new CheckboxTreeItem() { Value="C", Text="一级C", Index="", Checked =true,
Items=new List<CheckboxTreeItem>() {
new CheckboxTreeItem() { Value="CA", Text="二级CA", Index="", Checked =true },
new CheckboxTreeItem() { Value="CB", Text="二级CB", Index="", Checked =true,
Items=new List<CheckboxTreeItem>() {
new CheckboxTreeItem() { Value="CBA", Text="三级CBA", Index="", Checked =true },
new CheckboxTreeItem() { Value="CBB", Text="三级CBB", Index="", Checked =true },
}
},
}
},
}; return View(cb);
} [HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult test(List<CheckboxTreeItem> CheckboxTree, int id = )
{
ViewBag.IsEdit = id == ? false : true; return View(CheckboxTree);
}

下图是Controller接收到的参数:(运行调试,断点查看第27-31行代码)

另外还有自定义样式文件 CheckboxTree.css

 /*
author:熊学浩
time:2016年6月5日
description:树形菜单控件(有问题请致信:xiongzaiqiren@163.com),或者请参考【http://www.cnblogs.com/xiongzaiqiren/】
*/
/* CheckboxTree */
.CheckboxTree {
width: %;
height: %;
text-align: center;
margin: auto;
} .CBT-ul {
text-align: left;
list-style-type: disc;
} .CBT-ul .CBT-li {
display: list-item;
text-align: left;
margin-left: 10px;
font-size: 16px;
line-height: 20px;
word-wrap: break-word;
word-break: nomal;
list-style: inherit;
}
.CBT-li label {
cursor: pointer;
}
.CBT-li label input[type="checkbox"] {
width: 16px;
height: 16px;
padding: 5px ;
} .CBT-li span { } .CBT-li a:link, .CBT-li a:visited {
} .CBT-li a:hover, .CBT-li a:active {
color: #ffffff;
background-color: #;
} .CBT-li a.active {
color: #ffffff;
background-color: #;
} .CBT-li a span { }

CheckboxTree.css

用于初始化和设置选择状态改变的自定义javascript文件 CheckboxTree.js

 /*
author:熊学浩
time:2016年6月5日
description:树形菜单控件(有问题请致信:xiongzaiqiren@163.com),或者请参考【http://www.cnblogs.com/xiongzaiqiren/】
*/
/* CheckboxTree */
function setCheckboxTreeItemValue(dom) {
try {
if (!!dom)
dom.value = (!!dom.checked)
}
catch (e) {
console.log(e.message);
}
};
function iniCheckboxTree() {
try {
var cbList = document.getElementsByTagName("input");
if (!!cbList && cbList.length > ) {
for (var i = ; i < cbList.length; i++) {
if (!!cbList[i] && (cbList[i].type == "checkbox")) {
if (!!cbList[i].value) {
cbList[i].checked = (cbList[i].value.toLowerCase() == "true") || false;
}
}
}
}
}
catch (e) {
console.log(e.message);
}
}; if (!!window)
window.onload = iniCheckboxTree();
else
iniCheckboxTree();

CheckboxTree.js

最后,UI效果图:

【完】

MVC树控件,mvc中应用treeview,实现复选框树的多层级表单控件的更多相关文章

  1. easyui复选框树动态加载后台数据,实现自动选中数据库中数据。后台语言是.NET

    最近公司做项目用到了easyui复选框树来实现加载不同类型产品.因为我刚刚毕业,现在也算是实习吧,所以一脸懵逼啊.在公司里的一个哥的帮助下 ,我写出来这个EasyUi复选框树了,虽然东西不难,但也是自 ...

  2. Java通过复选框控件数组实现添加多个复选框控件

    编写程序,通过复选框控件数组事先选择用户爱好信息的复选框,在该程序中,要求界面中的复选框数量可以根据指定复选框名称的字符串数组的长度来自动调节. 思路如下: 创建JPanel面板对象: 使用JPane ...

  3. extjs 中动态给gridpanel 复选框赋值

    最近在搞extjs时需要动态根据数据给gridpanel的复选框赋值 网上看了很多 ,多不行,最后找到一个好使的方法 如下: RBACformPanel.getSelectionModel().sel ...

  4. 关于netbeans中的JComboBox(复选框)

    以最近写的选课系统中添加课程项为例 1.往复选框中放入选项(根据数据库添加) (1)首先将  属性—>model中默认Item1234清空 (2)获得数据库中的数据并放入. SelectCour ...

  5. 关于Unity中NGUI的Checkbox复选框、Slider滑动条和Button的6种触发回调事件的方式

    Checkbox复选框 1.创建一个NGUI背景Sprite1节点 2.打开NGUI---->Open---->Prefab Toolbar---->选择一个复选框节点,拖拽到背景节 ...

  6. QTreeView/QTableView中利用QStandardItem实现复选框三种形态变化

    https://www.techieliang.com/2017/12/729/ 原文地址 using_checkbox_item.h /** * @file using_checkbox_item. ...

  7. [原创]delphi一次性批量在TScrollBox中显示N个复选框TCheckBox的源码

    unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...

  8. Extjs3.4 grid中添加一列复选框

    var sm = new Ext.grid.CheckboxSelectionModel(); var cm = new Ext.grid.ColumnModel( [ sm, new Ext.gri ...

  9. mui开发中获取单选按钮、复选框的值

    js获取单选按钮的值 function getVals(){ var res = getRadioRes('rds'); if(res == null){mui.toast('请选择'); retur ...

随机推荐

  1. 以项目谈WebGIS中Web制图的设计和实现

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景介绍 一般WebGIS项目中,前端展示数据的流程基本是先做数据入 ...

  2. 深入理解CSS六种颜色模式

    前面的话 赏心悦目的颜色搭配让人感到舒服,修改元素颜色的功能让人趋之若鹜.但颜色规划不当,会让网站用户无所适从.颜色从<font color="">发展至今,保留了很多 ...

  3. log4net使用手册

    1. log4net简介 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.Java平台下,它还 ...

  4. 在 Windows7 上按照 MySQL5.7

    在 Windows7 上按照 MySQL5.7 1.从官网下载最新版本的 MySQL,这里下载的是 mysql-5.7.17-win32: 2.将下载的 mysql-5.7.17-win32.zip ...

  5. VS2015 Git 源码管理工具简单入门

    1.VS Git插件 1.1 环境 VS2015+GitLab 1.2 Git操作过程图解 1.3 常见名词解释 拉取(Pull):将远程版本库合并到本地版本库,相当于(Fetch+Meger) 获取 ...

  6. 学习笔记:delphi之TStringGrid

    1.说明 最近加入了一个项目组,使用的开发工具是delphi6,想想又要开始搞这个工具有点小忧伤,但没办法谁让咱就是个打杂的尼... 的需求是显示一个类似于Word/excel的那种表格,可以合并列等 ...

  7. 锤子OneStep及BigBang使用体验

    令人期待的Smartisan OS v3.1.2终于推送了,第一时间下载了更新.几乎花了半个小时才升级完毕,捧着还热乎的手机,赶忙体验一下传说中的两大杀器:OneStep以及BigBang. 先说On ...

  8. EasyPR--开发详解(4)形态学操作、尺寸验证、旋转等操作

    在上一篇深度分析与调优讨论中,我们介绍了高斯模糊,灰度化和Sobel算子.在本文中,会分析剩余的定位步骤. 根据前文的内容,车牌定位的功能还剩下如下的步骤,见下图中未涂灰的部分. 图1 车牌定位步骤 ...

  9. C#对WebApi数据操作

    目标 简化并统一程序获取WebApi对应实体数据的过程,方便对实体进行扩充.原理就是数据服务使用反射发现数据提供者,处理好泛型就行. 相关传送门:Restful WebApi开发实践 先来看下最后的请 ...

  10. ABP源码分析十:Unit Of Work

    ABP以AOP的方式实现UnitOfWork功能.通过UnitOfWorkRegistrar将UnitOfWorkInterceptor在某个类被注册到IOCContainner的时候,一并添加到该类 ...