类似于多层级的角色与权限控制功能,用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. [systemtap手记]debian体系安装过程

    Debian体系,本人测试用机 Ubuntu 11.10 uname -r 查看原本的内核版本为 3.0.0-12-generic 第一步: 安装systemtap包 $ sudo apt-get i ...

  2. iOS微信里打开app,Universal Links

    这两天在弄分享,从第三方应用或者浏览器打开自己app的东西 传统的方式是通过URL Scheme的方式,但是iOS9以后又出了新的更完美的方式Universal Links. 传统的URL Schem ...

  3. Android 工具-adb

    Android 工具-adb 版权声明:本文为博主原创文章,未经博主允许不得转载. Android 开发中, adb 是开发者经常使用的工具,是 Android 开发者必须掌握的. Android D ...

  4. [转载]SQL语句中的日期计算

    1. 本月的第一天SELECT  DATEADD(mm,  DATEDIFF(mm,0,getdate()),  0) 2. 本月的最后一天SELECT  dateadd(ms,-3,DATEADD( ...

  5. iOS开源项目周报1222

    由OpenDigg 出品的iOS开源项目周报第二期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开发方面的开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. io ...

  6. 和我一起看API(一)你所不知道的LinearLayout补充

    楼主英语水平差,翻译的不好的话请多多指正,嘿嘿... A Layout that arranges its children in a single column or a single row. T ...

  7. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

  8. Win7安装MySQL-5.7.16过程

    1.在C盘新建MYSQL文件夹:2.将mysql-5.7.16-winx64拷贝到C:\MYSQL文件夹下,更名为mysql-5.7.16:3.在mysql-5.7.16目录下,建my.ini文件,内 ...

  9. springMVC初始化绑定器

    单日期 在处理器类中配置绑定方法  使用@InitBinder注解 在这里首先注册一个用户编辑器 参数一为目标类型   propertyEditor为属性编辑器,此处我们选用 CustomDateEd ...

  10. 初探java中this的用法

    一般this在各类语言中都表示“调用当前函数的对象”,java中也存在这种用法: public class Leaf { int i = 0; Leaf increment(){ i++; retur ...