类似于多层级的角色与权限控制功能,用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. js中判断对象具体类型

    大家可能知道js中判断对象类型可以用typeof来判断.看下面的情况 <script> alert(typeof 1);//number alert(typeof "2" ...

  2. Nginx服务器之基础学习

    一.Nginx介绍 nginx:Nginx是一种软件服务器(轻量级),故它最主要的功能就是可以与服务器硬件结合,我们的应用程序可以放在nginx服务器上进行发布,已达到让网民浏览的效果.除此自外,Ng ...

  3. ajax.abort 终止AJAX请求

                               $(document).ready(function () { var ajax; $('#choice').change(function() ...

  4. yii 自动生成的内容,分页信息(Displaying 1-10 of 15 results.)如何修改或是yii cgridview template summary

    问的白一点就是 Displaying 1-10 of 15 results 如何翻译 如果搜索的话, 搜这个会出来很多内容 yii cgridview template summary 好了,其他不说 ...

  5. Handsontable对单元格的操作

    1.自动填充单元格数据 fillHandle:true/false    //当值为true时,允许拖动单元格右下角,将其值自动填充到选中的单元格 2.合并单元格 mergeCells:[{row:起 ...

  6. 【转】Eclipse自动补全的设置方法

    转自:http://blog.csdn.net/xiadasong007/archive/2009/11/11/4799715.aspx 打开 Eclipse -> Window -> P ...

  7. python for else

    http://blog.sina.com.cn/s/blog_5357c0af01013mwn.html raw_input() 与 input() __ Python http://www.cnbl ...

  8. STM32-USB那点事

    STM32 USB那点事1 USB那点事2 - Custom HID例子程序解疑 USB那点事3 -使用端口2作为custom HID的传输 USB那点事5之USB通信出错 USB那点事6传输要素 S ...

  9. C++引用的作用

    引入 C语言中函数有两种传参的方式: 传值和传址.以传值方式, 在函数调用过程中会生成一份临时变量用形参代替, 最终把实参的值传递给新分配的临时变量即形参. 它的优点是避免了函数调用的副作用, 确无法 ...

  10. EF_DataFrist遇到的问题

    正在 Code First 模式下将此上下文与从 EDMX 文件生成的用于 Database First 或 Model First 开发的代码一起使用.这将无法正常工作.若要解决此问题,请不要删除引 ...