MVC html 控件扩展【转载】
项目中用到mvc2控件扩展,任务分给了我,开发完了,结果可能要用devexpress,费了不少功夫,网上查找资料,整理成符合项目的,自己留个备份吧,一起学习
DropDownTree
第一个控件是DropDownTree,名字很形象,类似DropDownList显示形式,下拉树仿照zTree外观,比较简单,思路是后台生成HTML+jquery脚本(还有一种思路是直接通过js加载json数据不过这个不会,希望有人熟悉的给个例子)。
首先,在Scripts文件夹下新增一个js文件命名为DropDownTree.js,脚本代码如下:
1 var consts = { 2 line: { 3 ROOT: "root", 4 ROOTS: "roots", 5 CENTER: "center", 6 BOTTOM: "bottom", 7 NOLINE: "noline", 8 LINE: "line" 9 }, 10 folder: { 11 OPEN: "open", 12 CLOSE: "close", 13 DOCU: "docu" 14 }, 15 node: { 16 CURSELECTED: "curSelectedNode", 17 A_NONE: "a_node_none" 18 } 19 } 20 21 $(function () { 22 $(".DropDownTree").dblclick(function () { //双击事件清空文本,但不清楚下拉列表选项记录 23 $(this).attr("value", ""); 24 hideMenu("Div_menu_" + $(this).attr("id").split("_").pop()); 25 }).click(function () { //单击显示列表哦 26 var $this = $(this); 27 var textId = $this.attr("id").split("_").pop(); 28 var menuId = "Div_menu_" + $this.attr("id").split("_").pop(); 29 showMenu(textId, menuId); 30 }); 31 32 //a标签绑定clice 事件 33 $(".a_node_none,.curSelectedNode").bind("click", function () { 34 var aIdArr = $(this).attr("id").split("_"); 35 //debugger; 36 $(".curSelectedNode").each(function () {//遍历 37 var thisId = $(this).attr("id").split("_"); 38 if (thisId[2] == aIdArr[2]) { 39 $(this).removeClass(consts.node.CURSELECTED).addClass(consts.node.A_NONE).end(); 40 } 41 }); 42 43 $(this).addClass(consts.node.CURSELECTED).end(); 44 45 if ($(this).attr("canSelect") == "true") { 46 $spNode = $(this).children(".sp_tree"); 47 $("#" + $spNode.attr("id").split("_").pop()).val($spNode.html()); 48 } 49 else { 50 alert("该节点不能被选择"); 51 } 52 }); 53 54 55 }); 56 57 58 59 //textContent:TextBox's ID 60 //menuContent: 下拉div ID 61 function showMenu(textContent, menuContent) { 62 63 var treeDownObj = $("#" + textContent); 64 var treeDownOffset = $("#" + textContent).offset(); 65 $("#" + menuContent).css({ left: treeDownOffset.left + "px", top: treeDownOffset.top + treeDownObj.outerHeight() + "px" }).slideDown("fast"); 66 67 $("body").bind("mousedown", { id: menuContent }, onBodyDown); 68 69 //增加双击事件 70 $('.a_node_none,.curSelectedNode').dblclick(function () { 71 var menu = "Div_menu_" + textContent 72 hideMenu(menu); 73 }); 74 75 } 76 77 function hideMenu(menuid) { 78 $("#" + menuid).fadeOut("fast"); 79 $("body").unbind("mousedown", onBodyDown); 80 } 81 82 function onBodyDown(event) { 83 //获取事件 84 var e = event || window.event; 85 //获取元素 86 var originElement = $(e.target || e.srcElement); 87 var employeId = event.data.id.split("_"); //参数 88 var eventid = event.target.id.split("_"); 89 if (!(employeId.pop() == eventid.pop())) { 90 hideMenu(event.data.id); 91 } 92 } 93 94 function bambooClick(obj) { 95 var $obj = $(obj); 96 var bamClass = $(obj).attr("class"); 97 if (bamClass != "center_docu" || bamClass != "bottom_docu") { 98 var ulid = $obj.attr("id").toString().replace("bt", "ul"); 99 if (bamClass.indexOf(consts.folder.OPEN) > -1) {//隐藏100 if (bamClass.indexOf(consts.line.BOTTOM) > -1) {//last tree bamboo 区分bottom101 $(obj).removeClass("bottom_open").addClass("bottom_close"); //bamboo102 $(obj).next("a").children(".ico_open").removeClass("ico_open").addClass("ico_close"); //file Icon103 $(obj).siblings("ul").hide(); //$("#" + ulid).hide(); //item104 }105 else { //非bottom bamboo106 $(obj).removeClass("center_open").addClass("center_close"); //bamboo107 $(obj).next("a").children(".ico_open").removeClass("ico_open").addClass("ico_close"); //file Icon108 var child = $(obj).children();109 $(obj).siblings("ul").hide();110 }111 112 }113 else {//展开 center_docu114 if (bamClass.indexOf(consts.line.BOTTOM) > -1) {//tree last bamboo115 $(obj).removeClass("bottom_close").addClass("bottom_open"); //bamboo116 $(obj).next("a").children(".ico_close").removeClass("ico_close").addClass("ico_open"); //file Icon117 $(obj).siblings("ul").show();118 //$("#" + ulid).show(); //item119 }120 else {121 $(obj).removeClass("center_close").addClass("center_open"); //bamboo122 $(obj).next("a").children(".ico_close").removeClass("ico_close").addClass("ico_open"); //file Icon123 $(obj).siblings("ul").show(); //$("#" + ulid).show(); //item124 }125 }126 }127 }
其次,是样式文件,在Content下新增文件夹,这里命名为DownTreeStyle,在这个文件夹下新增新文件夹命名为img(放置在Tree图片,具体从网上下载,我用的3.0的),在DownTreeStyle文件夹下新增样式文件DownzTreeStyle.css,样式如下:
1 /*------------------------------------- 2 zTree Style version: 3.0 3 修改日期:2012.1.6,殷懂礼 4 -------------------------------------*/ 5 6 .ztree * {padding:0; margin:0; font-size:12px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif} 7 .ztree {margin:0; padding:5px; color:#333} 8 .ztree li{padding:0; margin:0; list-style:none; line-height:14px; text-align:left; white-space:nowrap} 9 .ztree li ul{ margin:0; padding:0 0 0 18px}10 .ztree li ul.line{ background:url(./img/line_conn.gif) 0 0 repeat-y;}11 12 .ztree li a {padding:1px 3px 0 0; margin:0 10px 0 0; cursor:pointer; height:16px; color:#333; background-color: transparent;13 text-decoration:none; vertical-align:top; display: inline-block}14 .ztree li a:hover {text-decoration:underline;background-color:#fbec88;}15 .ztree li a.curSelectedNode {padding-top:0px; background-color:#FFE6B0; color:black; border:1px #FFB951 solid;16 opacity:0.8; filter:alpha(opacity=80)}17 .ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#FFE6B0; color:black;18 border:1px #FFB951 solid; opacity:0.8; filter:alpha(opacity=80)}19 .ztree li a.tmpTargetNode {padding-top:0px; background-color:#316AC5; color:white; border:1px #316AC5 solid;20 opacity:0.8; filter:alpha(opacity=80)}21 .ztree li a input.rename {height:14px; width:80px; padding:0; margin:0;22 font-size:12px; border:1px #7EC4CC solid; *border:0px}23 .ztree li span {line-height:16px; margin-right: 2px}24 .ztree li button {width:16px; height:16px; vertical-align:middle; border:0 none; cursor: pointer;25 background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;26 background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")}27 /* 这段代码暂时没有用的上28 .ztree li button.chk {width:13px; height:13px; margin:0 3px 0 0; cursor: auto}29 .ztree li button.chk.checkbox_false_full {background-position:0 0}30 .ztree li button.chk.checkbox_false_full_focus {background-position:0 -12px}31 .ztree li button.chk.checkbox_true_full {background-position:0 -24px}32 .ztree li button.chk.checkbox_true_full_focus {background-position:0 -36px}33 .ztree li button.chk.checkbox_true_part {background-position:0 -48px}34 .ztree li button.chk.checkbox_true_part_focus {background-position:0 -60px}35 .ztree li button.chk.checkbox_false_part {background-position:0 -72px}36 .ztree li button.chk.checkbox_false_part_focus {background-position:0 -84px}37 .ztree li button.chk.radio_false_full {background-position:-13px 0}38 .ztree li button.chk.radio_false_full_focus {background-position:-13px -12px}39 .ztree li button.chk.radio_true_full {background-position:-13px -24px}40 .ztree li button.chk.radio_true_full_focus {background-position:-13px -36px}41 .ztree li button.chk.radio_true_part {background-position:-13px -48px}42 .ztree li button.chk.radio_true_part_focus {background-position:-13px -60px}43 .ztree li button.chk.radio_false_part {background-position:-13px -72px}44 .ztree li button.chk.radio_false_part_focus {background-position:-13px -84px}45 */46 .ztree li button.switch {width:18px; height:18px}47 .ztree li button.root_open{background-position:-62px -54px}48 .ztree li button.root_close{background-position:-44px -54px}49 .ztree li button.roots_open{background-position:-62px 0}50 .ztree li button.roots_close{background-position:-44px 0}51 .ztree li button.center_open{background-position:-62px -18px}52 .ztree li button.center_close{background-position:-44px -18px}53 .ztree li button.bottom_open{background-position:-62px -36px}54 .ztree li button.bottom_close{background-position:-44px -36px}55 .ztree li button.noline_open{background-position:-62px -72px}56 .ztree li button.noline_close{background-position:-44px -72px}57 .ztree li button.root_docu{ background:none;}58 .ztree li button.roots_docu{background-position:-26px 0}59 .ztree li button.center_docu{background-position:-26px -18px}60 .ztree li button.bottom_docu{background-position:-26px -36px}61 .ztree li button.noline_docu{ background:none;}62 63 .ztree li button.ico_open{margin-right:2px; background-position:-80px -16px; vertical-align:top; *vertical-align:middle}64 .ztree li button.ico_close{margin-right:2px; background-position:-80px 0; vertical-align:top; *vertical-align:middle}65 .ztree li button.ico_docu{margin-right:2px; background-position:-80px -32px; vertical-align:top; *vertical-align:middle}66 .ztree li button.edit {margin-right:2px; background-position:-80px -48px; vertical-align:top; *vertical-align:middle}67 .ztree li button.remove {margin-right:2px; background-position:-80px -64px; vertical-align:top; *vertical-align:middle}68 69 .ztree li button.ico_loading{margin-right:2px; background:url(./img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}70 71 72 ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)}73 74 button.tmpzTreeMove_arrow {width:16px; height:16px; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute;75 background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;76 background-position:-80px -80px; background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")}77 78 ul.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:auto; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)}79 .zTreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute}80 81 82 /*树下拉列表样式*/83 ul.ztree {margin-top: 10px;border: 1px solid #617775;background: #ffffff;width:220px;height:360px;overflow-y:scroll;overflow-x:auto;}84 ul.log {border: 1px solid #617775;background: #f0f6e4;width:300px;height:170px;overflow: hidden;}85 ul.log.small {height:45px;}86 ul.log li {color: #666666;list-style: none;padding-left: 10px;}87 ul.log li.dark {background-color: #E3E3E3;}88 89 90 /* level 等级样式*/91 /*.ztree li button.level0 {92 display:none;93 }94 .ztree li ul.level0 {95 padding:0;96 background:none;97 }*/
然后,是mvc控件扩展,这里命名为DropDownTreeExtension.cs,代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Web.Mvc; 6 using System.Web.Routing; 7 8 namespace MVC.Extensions 9 { 10 /// <summary> 11 /// 下拉树控件 12 /// 作者:殷懂礼 13 /// 修正时间:2012-1-5 14 /// </summary> 15 public static class OmsDropDownTree 16 { 17 18 //完整控制 19 public static MvcHtmlString DropDownTree(this HtmlHelper helper, List<Node> treeSource, string id, 20 string defaultIndex, string defaultValue, float? menuWidth, 21 float? menuHeight, object htmlAttribute, bool enableEdit, bool canSelectParent 22 ) 23 { 24 return MvcHtmlString.Create(GeneriteDropDownTreeStr(treeSource, id, defaultIndex, defaultValue, menuWidth, menuHeight, htmlAttribute, enableEdit, canSelectParent)); 25 } 26 27 //实施默认index 和 下拉列表的高度和宽度 28 public static MvcHtmlString DropDownTree(this HtmlHelper helper, List<Node> treeSource, string id, string defaultIndex, float menuWidth, float menuHeight) 29 { 30 return MvcHtmlString.Create(GeneriteDropDownTreeStr(treeSource, id, defaultIndex, null, menuWidth, menuHeight)); 31 } 32 33 //添加一个defaultIndex 设置 默认选择值的id 列表默认选择 用于编辑修改页面 34 public static MvcHtmlString DropDownTree(this HtmlHelper helper, List<Node> treeSource, string id, string defaultIndex) 35 { 36 return MvcHtmlString.Create(GeneriteDropDownTreeStr(treeSource, id, defaultIndex)); 37 } 38 39 //默认参数最少 新增时候可以用这个 无默认选择值 40 public static MvcHtmlString DropDownTree(this HtmlHelper helper, List<Node> treeSource, string id) 41 { 42 return MvcHtmlString.Create(GeneriteDropDownTreeStr(treeSource, id)); 43 } 44 45 46 /// <summary> 47 /// 自定义控件文本树控件 48 /// </summary> 49 /// <param name="treeSource">树数据源</param> 50 /// <param name="id">文本树页面元素id属性,注意当前页面id必须唯一,且该id不能用下划线“_”</param> 51 /// <param name="defaultIndex">默认选择树形列表的数据源索引值及节点的唯一id表示,用于编辑样式时填充数据</param> 52 /// <param name="defaultValue">文本框默认值</param> 53 /// <param name="menuWidth">设置列表宽度,默认200px</param> 54 /// <param name="menuHeight">设置列表宽度,默认自动</param> 55 /// <param name="htmlAttribute">自定义的一些控件属性</param> 56 /// <param name="readOnly">默认只读属性</param> 57 /// <param name="canSelectParent">不可选择父节点</param> 58 /// <returns></returns> 59 public static string GeneriteDropDownTreeStr(List<Node> treeSource, string id, string defaultIndex = null, string defaultValue = null, 60 float? menuWidth = 200, float? menuHeight = null, object htmlAttribute = null, bool? readOnly = false, bool? canSelectParent = false ) 61 { 62 if (treeSource == null) 63 throw new ArgumentNullException("treeSource", "参数treeSource 不能为空"); 64 if (id.IndexOf("_") >= 0) 65 return "<h1 style=\"color:red;\">DropDownTree控件id 不能包含下环线‘_’<h1>"; 66 67 bool isHead = true; 68 string callbackValue = ""; 69 70 StringBuilder responseStr = new StringBuilder();//返回整体 71 List<NodeEx> changedList = new List<NodeEx>(); 72 73 string menuTreeContent = "Div_menu_" + id; 74 //responseStr.AppendFormat("<a id='menuBtn' href='#' οnclick=\"showMenu('{0}','{1}')\">选择</a>", ID, menuTreeContent);// 75 76 //render List div and generate a ID for it 77 78 responseStr.AppendFormat(" <div id='{0}' class='menuContent' style='display: none; position: absolute;'> ", menuTreeContent); 79 80 if (isHead) 81 { 82 string height = ""; 83 if (menuHeight != null) 84 height = "height:" + menuHeight.ToString() + "px; "; 85 responseStr.AppendFormat(" <ul id='ul_{0}' class='ztree' style='width: {1}px; {2} margin-top: 0px;'>", id, menuWidth.ToString(), height);//menuContent 86 } 87 //canSelectParent = ; 88 RenderTreeContent(treeSource, changedList, null, id, ref isHead, responseStr, defaultIndex, ref callbackValue, Convert.ToBoolean(canSelectParent)); 89 responseStr.AppendFormat("</div>"); 90 91 //render TextBox partial 92 var textBox = new TagBuilder("input"); 93 textBox.GenerateId(id); 94 textBox.Attributes.Add("type", "text"); 95 96 if (defaultValue != null && defaultIndex == null) 97 { 98 string value = defaultValue.ToString(); 99 textBox.Attributes.Add("value", value);100 }101 102 if (!string.IsNullOrEmpty(callbackValue))103 {104 textBox.Attributes.Add("value", callbackValue);105 }106 107 if (!Convert.ToBoolean(readOnly))108 {109 textBox.Attributes.Add("readonly", "true");110 }111 112 textBox.Attributes.Add("class", "DropDownTree");//文本样式113 textBox.MergeAttributes(new RouteValueDictionary(htmlAttribute));114 return textBox.ToString(TagRenderMode.SelfClosing) + responseStr.ToString();115 }116 /// <summary>117 /// 渲染树控件内容部分118 /// </summary>119 /// <param name="treeSource">树数据源</param>120 /// <param name="processedSource">加工过的数据源</param>121 /// <param name="parentId">父节点id</param>122 /// <param name="controlId">树控件id</param>123 /// <param name="isHead">是否是头节点</param>124 /// <param name="menuTreeStr">下拉树拼接字符串</param>125 /// <param name="selectIndex">选中的节点索引值</param>126 /// <param name="callbackValue">选中节点的显示值</param>127 public static void RenderTreeContent(List<Node> treeSource, List<NodeEx> processedSource, string parentId, string controlId,128 ref bool isHead, StringBuilder menuTreeStr, string selectIndex, ref string callbackValue, bool canSelectParent)129 {130 List<NodeEx> layerNodes = ExNodeList(treeSource, parentId, processedSource);131 for (int i = 0; i < layerNodes.Count(); i++)132 {133 string aStyle = "a_node_none";134 if (layerNodes[i].Id == selectIndex)135 {136 callbackValue = layerNodes[i].Text;137 aStyle = "curSelectedNode";138 }139 140 string bambooStyle = "";141 if (isHead)142 {143 if (layerNodes[i].HasChild)//default open 144 bambooStyle = BambooStyle.CenterOpen;145 else146 bambooStyle = BambooStyle.Head;147 }148 else if (!layerNodes[i].HasNext)149 {150 if (!layerNodes[i].HasChild)151 bambooStyle = BambooStyle.Bottom;152 else153 bambooStyle = BambooStyle.CenterOpen;154 }155 else if (layerNodes[i].HasChild)//还可以增加一个判断 树是展开还是收缩156 bambooStyle = BambooStyle.CenterOpen;//default open157 else158 bambooStyle = BambooStyle.CenterDocu;159 160 string folderFlag = "";161 if (layerNodes[i].HasChild)162 folderFlag = FolderStyle.FolderOpen.ToString();163 else164 folderFlag = FolderStyle.Fild.ToString();165 166 if (isHead && layerNodes[i].ParentId == null)167 {168 isHead = false;169 }170 171 if (layerNodes[i].IsLead && layerNodes[i].ParentId != null)172 {173 174 if (!layerNodes[i].HasNext && !layerNodes[i].IsLead)175 menuTreeStr.AppendFormat("<ul id='ul_{0}_{1}' style='display: block;'>", layerNodes[i].Id, controlId);176 else177 {178 NodeEx parent = processedSource.Single(m => m.Id == layerNodes[i].ParentId);179 if (layerNodes[i].HasNext && parent.HasNext)180 menuTreeStr.AppendFormat("<ul class='line' id='ul_{0}_{1}' style='display: block;'>", layerNodes[i].Id, controlId);//定义 ul 的id 命名规则 181 else182 menuTreeStr.AppendFormat("<ul id='ul_{0}_{1}' style='display: block;'>", layerNodes[i].Id, controlId);183 }184 185 }186 187 if (!isHead)188 menuTreeStr.AppendFormat("<li id='li_{0}_{1}'>", layerNodes[i].Id, controlId);//定义li的id命名规则 189 190 menuTreeStr.AppendFormat("<button title='' id='bt_{0}_{1}' class='{2}' type='button' οnclick='bambooClick(this)'></button>", layerNodes[i].Id, controlId, bambooStyle);191 192 //默认 父节点不可被选择193 string enableSelect = Convert.ToBoolean(canSelectParent) == true ? "true" : layerNodes[i].HasChild == true ? "false" : "true";194 menuTreeStr.AppendFormat("<a title='{0}' id='a_{1}_{2}' class='{3}' canSelect='{4}' >", layerNodes[i].Text, layerNodes[i].Id, controlId, aStyle, enableSelect);195 196 menuTreeStr.AppendFormat("<button type='button' class='{0}' id='btf_{1}_{2}'></button>", folderFlag, layerNodes[i].Id, controlId);197 198 menuTreeStr.AppendFormat("<span class='sp_tree' id='sp_{1}_{2}'>{3}</span>", controlId, layerNodes[i].Id, controlId, layerNodes[i].Text);199 menuTreeStr.AppendLine("</a>");200 201 NodeEx flag = layerNodes[i];202 203 RenderTreeContent(treeSource, processedSource, layerNodes[i].Id, controlId, ref isHead, menuTreeStr, selectIndex, ref callbackValue, canSelectParent); //递归调用204 205 if (layerNodes[i].ParentId == flag.ParentId)//遇到兄弟结单 结束标签206 menuTreeStr.AppendLine("</li>");207 if (layerNodes[i].ParentId == flag.ParentId && !layerNodes[i].HasNext)//结束ul208 menuTreeStr.AppendLine("</ul>");209 210 }211 212 }213 214 /// <summary>215 /// 对原生树节点扩展216 /// </summary>217 /// <param name="treeSorce">树数据源</param>218 /// <param name="parentId">父节点id</param>219 /// <param name="processedSource">被扩展后的所有节点集合</param>220 /// <returns>parentId的被扩展后的子节点集合</returns>221 public static List<NodeEx> ExNodeList(List<Node> treeSorce, string parentId, List<NodeEx> processedSource)222 {223 IEnumerable<Node> head = from node in treeSorce where node.ParentId == parentId select node;224 List<NodeEx> childList = new List<NodeEx>();225 bool isTop = true;226 int counter = 0;227 foreach (Node item in head)228 {229 NodeEx node = new NodeEx();230 node.Id = item.Id;231 node.Text = item.Text;232 node.ParentId = item.ParentId;233 234 if (isTop)// is head only one control by ref 235 {236 node.IsLead = true;237 isTop = false;238 }239 else240 node.IsLead = false;241 242 if (counter == head.Count() - 1)//是否有下一个兄弟243 node.HasNext = false;244 else245 node.HasNext = true;246 247 IEnumerable<Node> hasChild = from child in treeSorce where child.ParentId == item.Id select child;248 249 if (hasChild.Count() > 0)//是否有孩子250 node.HasChild = true;251 else252 node.HasChild = false;253 childList.Add(node);254 processedSource.Add(node);255 counter++;256 }257 return childList;258 }259 260 }261 262 //树节点263 public struct Node264 {265 /// <summary>266 /// 节点id267 /// </summary>268 public string Id { get; set; }269 /// <summary>270 /// 显示值271 /// </summary>272 public string Text { get; set; }273 /// <summary>274 /// 父节点id275 /// </summary>276 public string ParentId { get; set; }277 }278 279 //内部扩展节点结构,类280 public struct NodeEx281 {282 /// <summary>283 /// id284 /// </summary>285 public string Id { get; set; }286 287 /// <summary>288 /// 显示值289 /// </summary>290 public string Text { get; set; }291 292 /// <summary>293 /// 父节点id294 /// </summary>295 public string ParentId { get; set; }296 297 /// <summary>298 /// 是否是节点开头299 /// </summary>300 public bool IsLead { get; set; }//竹头展开样式301 302 /// <summary>303 /// 是否有下个兄弟节点304 /// </summary>305 public bool HasNext { get; set; } //最后一个ul 中线306 /// <summary>307 /// 是否有孩子节点308 /// </summary>309 public bool HasChild { get; set; }//是否有孩子310 }311 312 //bambo的样式(树节点的 展开和关闭控制样式名称)313 public static class BambooStyle314 {315 //根节点,没有字节点时的样式(E字头)316 public const string Head = "roots_docu";317 //有子节点,且节点展开318 public const string CenterOpen = "center_open";319 //有子节点,且节点关闭320 public const string CenterClose = "center_close";321 // 没有子节点322 public const string CenterDocu = "center_docu";323 //结尾节点324 public const string Bottom = "bottom_docu";325 }326 327 //树文件夹或文件样式328 public static class FolderStyle329 {330 //文件夹打开样式331 public const string FolderOpen = "ico_open";332 //文件夹关闭样式333 public const string FolderClose = "ico_close";334 //文件样式335 public const string Fild = "ico_docu";336 }337 }
最后,是用法了:
- 在Master页,或者当前页,引入jquery最好是高版本的、DropDownTree.js、DownzTreeStyle.css;
- 在controller中构造 一些数据,代码如下:
Action 方法
public ActionResult TextDownTree() { List<Node> source = new List<Node>(); for (int i = 0; i < 3; i++) { Node tree = new Node(); tree.Id = i.ToString(); tree.Text = "北京" + i.ToString(); source.Add(tree); for (int j = 0; j < 3; j++) { Node child = new Node(); child.ParentId = i.ToString(); child.Id = i.ToString() + j.ToString(); child.Text = "北京_" + i.ToString() + j.ToString(); source.Add(child);for (int k = 0; k < 3; k++) { Node childs = new Node(); childs.ParentId = child.Id; childs.Id = i.ToString() + j.ToString() + k.ToString(); childs.Text = "北京_" + i.ToString() + "_" + j.ToString() + "_" + k.ToString(); source.Add(childs); } } } ViewData["tree"] = source; ViewData["index"] = "012";//默认选中的值 string encodeTestStr = "hello viewData <br/><br/> start wrapper"; ViewData["description"] = encodeTestStr; List<SelectListItem> radioList = new List<SelectListItem>();for (int i = 0; i < 5; i++) { SelectListItem sli = new SelectListItem(); sli.Selected = false; sli.Text = "RTxt-" + i.ToString(); sli.Value = "RVal-" + i.ToString(); radioList.Add(sli); } ViewData["radioList"] = radioList;// ds.Description = ss; return View("treeTest"); }
这里不要忘记对一些类的引用一些类在DropDownTreeExtension.cs中。
- 在View页面用<% Html.DropDownTree(参数.....)%>就可以完成了,例如:
View Code
1 <%=Html.DropDownTree(ViewData["tree"] as List<Node>,"test")%>2 <%=Html.DropDownTree(ViewData["tree"] as List<Node>, "test1", ViewData["index"].ToString())%>3 <%=Html.DropDownTree(ViewData["tree"] as List<Node>, "test2")%>4 <%:Html.DropDownTree(ViewData["tree"] as List<Node>, "test3", ViewData["index"].ToString(), null, 300, 100, new { parenid="899-"},true,true)%>
一些效果:
日历控件
第二个是日历控件,在网上查了一个普通的日历控件,也生成了下拉的日历样子,但是一些脚本比如选择年月,需要一些时间,最后只好套用了My97 DatePicker,这样以来其实简单多了。
第一步:下载 My97 DatePicker,我用的是 My97 DatePicker 4.72 Release。在Script文件夹下新增Calendar文件夹将My97相关文件放入这个文件夹中,如:
这些文件添加完成之后,在页面只需要引用WdataPicker.js即可(view 页面或者Master页面加载),例如:
<!--日历控件引用开始--> <script src="http://www.cnblogs.com/Scripts/Calendar/WdatePicker.js" type="text/javascript"></script> <!--日历控件引用结束-->
然后mvc的控件扩展,主要用到TextBox然后加一个Class名为Wdate,代码如下:
.Wdate{ border: #999 1px solid; /*height: 20px;*/ background: url("./images/datePicker.gif") no-repeat right;//My97 picture}
/// <summary>/// 日期控件 /// </summary> public static class CalendarExtensions {public static MvcHtmlString Calendar(this HtmlHelper helper) { StringBuilder sb = new StringBuilder(); TagBuilder textCalendar = new TagBuilder("input"); textCalendar.AddCssClass("Wdate"); textCalendar.Attributes.Add("type", "text"); textCalendar.Attributes.Add("onclick", "WdatePicker()");return MvcHtmlString.Create(textCalendar.ToString(TagRenderMode.SelfClosing)); } public static MvcHtmlString Calendar(this HtmlHelper helper, string id) { StringBuilder sb = new StringBuilder(); TagBuilder txtCalendar = new TagBuilder("input"); txtCalendar.AddCssClass("Wdate"); txtCalendar.Attributes.Add("type", "text"); txtCalendar.GenerateId(id); txtCalendar.Attributes.Add("onclick", "WdatePicker()");return MvcHtmlString.Create(txtCalendar.ToString(TagRenderMode.SelfClosing)); } public static MvcHtmlString Calendar(this HtmlHelper helper, string id, DateTime defaultDate) { StringBuilder sb = new StringBuilder(); TagBuilder txtCalendar = new TagBuilder("input"); txtCalendar.AddCssClass("Wdate"); txtCalendar.Attributes.Add("type", "text"); txtCalendar.GenerateId(id); txtCalendar.Attributes.Add("value", string.Format("{0:d}", defaultDate).Replace('/','-')); txtCalendar.Attributes.Add("onclick", "WdatePicker()");return MvcHtmlString.Create(txtCalendar.ToString(TagRenderMode.SelfClosing)); }}
这样用法就很简单了,在view页面
<% var date = new DateTime(2011, 12, 12); %> <%=Html.Calendar("tody",date)%>
效果:
这个My97如果想显示中文只需要在他的confg.js中配置,还有皮肤页面里面。
CheckButtonList和RadioButtonList
这两个控件其实是一样的代码,只是,根据传入参数的类型,一个生成的Radio一个生成的是CheckBox,其实也是直接生成的html然后把这些Radio 或者 checkbox 套到td中,
具体实现的C#代码如下:
/// <summary>/// radiobuttonList 和 checkboxList/// author:殷懂礼/// 修改时间:2012-1-16/// </summary> public static class CheckListExtensions {/// <summary>/// 内用 生成radio 或者 checkbox 并 可排列/// </summary>/// <param name="htmlHelper"></param>/// <param name="id">控件id</param>/// <param name="items">列表项源</param>/// <param name="canMultichoice">是否允许多选(false:radio;true: checkbox)</param>/// <param name="htmlAttribute">自定义属性</param>/// <param name="repeatColumns">排列列数</param>/// <param name="repeatDirection">排列方向</param>/// <returns></returns> public static MvcHtmlString InternalCheckButtonList(this HtmlHelper htmlHelper, string id, IEnumerable<SelectListItem> items, bool canMultichoice = false, object htmlAttribute = null,int repeatColumns = 1, RepeatDirection repeatDirection = RepeatDirection.Horizontal) {string mainTagId = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(id);if (string.IsNullOrEmpty(mainTagId)) {throw new ArgumentException("filed can't be null or empty !", "name"); } TagBuilder tableTag = new TagBuilder("table"); tableTag.AddCssClass("radio-main"); StringBuilder tableInnerContent = new StringBuilder();if (repeatColumns == 1)//默认单行或列排列 {if (repeatDirection == RepeatDirection.Horizontal)//默认 水平 单排列 {var trTag = new TagBuilder("tr");foreach (var item in items) {var tdTag = RenderRadioTd(htmlHelper, mainTagId, item, canMultichoice, htmlAttribute); trTag.InnerHtml = tdTag.ToString(); tableInnerContent.Append(trTag.ToString()); } }else//垂直 {foreach (var item in items) {var trTag = new TagBuilder("tr");var tdTag = RenderRadioTd(htmlHelper, mainTagId, item, canMultichoice, htmlAttribute); trTag.InnerHtml = tdTag.ToString(); tableInnerContent.Append(trTag.ToString()); } } }else//多行或列 排列 {int itemsCounter = items.Count();bool isPerfectDivid = itemsCounter % repeatColumns == 0 ? true : false;int repeatNumber = itemsCounter / repeatColumns; //重复次数 List<SelectListItem> itemList = items.ToList(); StringBuilder trContent = new StringBuilder(); TagBuilder trTag = new TagBuilder("tr"); for (int i = 0; i < itemsCounter; i++) { TagBuilder tdTag = RenderRadioTd(htmlHelper, mainTagId, itemList[i], canMultichoice, htmlAttribute); trContent.Append(tdTag.ToString());if (i != 0 && ((i + 1) % repeatColumns) == 0 && (i + 1) / repeatColumns != repeatNumber) { trTag.InnerHtml = trContent.ToString(); tableInnerContent.Append(trTag.ToString()); trContent.Clear(); }else if (i == itemsCounter - 1) { trTag.InnerHtml = trContent.ToString(); tableInnerContent.Append(trTag.ToString()); } } } tableTag.InnerHtml = tableInnerContent.ToString();return MvcHtmlString.Create(tableTag.ToString()); }/// <summary>/// 生成内部 的 td 所有内容/// </summary>/// <param name="htmlHelper"></param>/// <param name="mainTagName">主标签id</param>/// <param name="item">选项</param>/// <param name="canMultichoice">radio or checkbox</param>/// <param name="htmlAttribute">自定义属性</param>/// <returns></returns> private static TagBuilder RenderRadioTd(HtmlHelper htmlHelper, string mainTagName, SelectListItem item, bool? canMultichoice = false, object htmlAttribute = null) {var tdTag = new TagBuilder("td");var rbValue = item.Value ?? item.Text;var rbName = mainTagName + "_" + rbValue; //generate radio var radioTag = new TagBuilder("input"); radioTag.GenerateId(rbName); radioTag.MergeAttribute("value", rbValue); if (item.Selected) radioTag.MergeAttribute("checked", item.Selected.ToString()); string checkType = "";if (Convert.ToBoolean(canMultichoice)) checkType = "checkbox";else checkType = "radio"; radioTag.Attributes.Add("type", checkType); radioTag.MergeAttribute("name", mainTagName); radioTag.MergeAttributes(new RouteValueDictionary(htmlAttribute)); var labelTag = new TagBuilder("label"); labelTag.MergeAttribute("for", rbName); labelTag.MergeAttribute("id", rbName + "_label"); labelTag.InnerHtml = rbValue; tdTag.InnerHtml = radioTag.ToString() + labelTag.ToString();return tdTag; } }
富文本编辑器
用kinderEdit 使用方法特别注意,第一需要在web.config中<system.web> <httpRuntime requestValidationMode="2.0"/>配置这个属性,第二,在后台方法中配置[ValidateInput(false)]。第三,在.aspx 页面 配置 ValidateRequest=“false”
转载于:https://www.cnblogs.com/worfdream/articles/2561579.html
MVC html 控件扩展【转载】相关推荐
- wpf listview 添加控件_WPF开源控件扩展库 MaterialDesignExtensions
WPF开源控件扩展库 - MaterialDesignExtensions MaterialDesignExtensions仓库截图 logo Material Design Extensions 在 ...
- RxSwift UI控件扩展
RxSwift UI控件扩展 最好的示例是参考RxCocoa查看类似的属性如何扩展Rx化的. 为了配合RxSwift的绑定关系,RxCocoa提供简单的基于Cocoa控件的扩展,但是很少,比如Labe ...
- WPF开源控件扩展库 - MaterialDesignExtensions
WPF开源控件扩展库 - MaterialDesignExtensions MaterialDesignExtensions仓库截图 logo Material Design Extensions 在 ...
- 移动界面控件Essential Studio for Mobile MVC网格控件解析
移动界面控件Essential Studio for Mobile MVC是Syncfusion公司旗下一款企业级的用于移动应用开发的界面控件,整个套包中包含了grids.charts.gauges. ...
- Silverlight实用窍门系列:59.多个中心点联动多线的可拖动控件扩展为拓扑图
在本系列的第17篇文章中"Silverlight实用窍门系列:17.中心点联动多线的可拖动控件(绘制工程图.拓扑图基础) ",制作了基本的中心联动图标.有园友对此图的扩展不是很清晰 ...
- 移动界面控件Essential Studio for Mobile MVC图表控件解析
企业级的用于移动应用开发的界面控件Essential Studio for Mobile MVC中的Essential Chart for Mobile MVC是一款基于HTML 5的高性能且轻量化的 ...
- [ASP.NET]ScriptManager控件使用 转载
目录 概述 局部刷新 错误处理 类型系统扩展 注册定制脚本 注册 Web 服务 在客户端脚本中使用认证和个性化服务 ScriptManagerProxy 类 添加 ScriptManager 控件 客 ...
- C# 采用系统委托的方式处理线程内操作窗体控件(转载)
C# 采用系统委托的方式处理线程内操作窗体控件 C# / asp.net / j 2009-12-25 10:04:47 阅读138 评论0 字号:大中小 订阅 一.System.Windows. ...
- 初级软件实作 - 星便笺 - 之二 - 富文本控件扩展
便笺的主体做好了,最近一直觉得缺点儿什么,决定改变便笺的开发方向,把便笺做成一个开放平台. 开放平台好呀,只是缺点儿什么.什么呢?好的文本控件. 我希望文本控件能实现的功能: 纯正的文本控件 文字随意 ...
最新文章
- python【数据结构与算法】从一个例子引入动态规划❤️
- Codeforces Round #713 (Div. 3)
- VS C# DateTimePicker()的小技巧
- Linux内核线程kernel thread详解--Linux进程的管理与调度
- python 函数例子_Python3函数之例子
- linux c++编译问题和虚拟机网络通信
- Zabbix触发器和监控项设置时间范围.
- Linux下设置定期执行脚本
- 【人脸识别】基于matlab GUI SVM和PCA人脸识别【含Matlab源码 369期】
- 余晨:我终于采访到了马斯克,他是个腼腆的钢铁侠
- LoadRunner 压力测试
- E71(S60 3rd)通话录音软件 -终极录音- 的用法
- html 小游戏 俄罗斯方块
- 各个版本Microsoft Visual C++运行库下载
- 【转】BAT机器学习面试1000题系列(1~50)
- Kahan's summation Formula
- updated beforeUpdate() Updated() 生命周期-销毁阶段 vue的nextTick@stage3---week2--day4-1
- TiDB 在汽车之家818台网互动项目中的应用
- 边伯贤计算机系文,EXO◆『150920|搬文』边伯贤反攻记【中长/甜】
- matlab矩阵乘法运算结果不对,矩阵里乘法使用错误?