项目中用到mvc2控件扩展,任务分给了我,开发完了,结果可能要用devexpress,费了不少功夫,网上查找资料,整理成符合项目的,自己留个备份吧,一起学习

DropDownTree

第一个控件是DropDownTree,名字很形象,类似DropDownList显示形式,下拉树仿照zTree外观,比较简单,思路是后台生成HTML+jquery脚本(还有一种思路是直接通过js加载json数据不过这个不会,希望有人熟悉的给个例子)。

首先,在Scripts文件夹下新增一个js文件命名为DropDownTree.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,样式如下:

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,代码如下:

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 }

最后,是用法了:

  1. 在Master页,或者当前页,引入jquery最好是高版本的、DropDownTree.js、DownzTreeStyle.css;
  2. 在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中。

  3. 在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页面加载),例如:

My97 js 引用

    <!--日历控件引用开始-->    <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}

CalendarExtension.cs

    /// <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#代码如下:

CheckListExtension.cs

    /// <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 控件扩展【转载】相关推荐

  1. wpf listview 添加控件_WPF开源控件扩展库 MaterialDesignExtensions

    WPF开源控件扩展库 - MaterialDesignExtensions MaterialDesignExtensions仓库截图 logo Material Design Extensions 在 ...

  2. RxSwift UI控件扩展

    RxSwift UI控件扩展 最好的示例是参考RxCocoa查看类似的属性如何扩展Rx化的. 为了配合RxSwift的绑定关系,RxCocoa提供简单的基于Cocoa控件的扩展,但是很少,比如Labe ...

  3. WPF开源控件扩展库 - MaterialDesignExtensions

    WPF开源控件扩展库 - MaterialDesignExtensions MaterialDesignExtensions仓库截图 logo Material Design Extensions 在 ...

  4. 移动界面控件Essential Studio for Mobile MVC网格控件解析

    移动界面控件Essential Studio for Mobile MVC是Syncfusion公司旗下一款企业级的用于移动应用开发的界面控件,整个套包中包含了grids.charts.gauges. ...

  5. Silverlight实用窍门系列:59.多个中心点联动多线的可拖动控件扩展为拓扑图

    在本系列的第17篇文章中"Silverlight实用窍门系列:17.中心点联动多线的可拖动控件(绘制工程图.拓扑图基础) ",制作了基本的中心联动图标.有园友对此图的扩展不是很清晰 ...

  6. 移动界面控件Essential Studio for Mobile MVC图表控件解析

    企业级的用于移动应用开发的界面控件Essential Studio for Mobile MVC中的Essential Chart for Mobile MVC是一款基于HTML 5的高性能且轻量化的 ...

  7. [ASP.NET]ScriptManager控件使用 转载

    目录 概述 局部刷新 错误处理 类型系统扩展 注册定制脚本 注册 Web 服务 在客户端脚本中使用认证和个性化服务 ScriptManagerProxy 类 添加 ScriptManager 控件 客 ...

  8. C# 采用系统委托的方式处理线程内操作窗体控件(转载)

    C# 采用系统委托的方式处理线程内操作窗体控件 C# / asp.net / j 2009-12-25 10:04:47 阅读138 评论0   字号:大中小 订阅 一.System.Windows. ...

  9. 初级软件实作 - 星便笺 - 之二 - 富文本控件扩展

    便笺的主体做好了,最近一直觉得缺点儿什么,决定改变便笺的开发方向,把便笺做成一个开放平台. 开放平台好呀,只是缺点儿什么.什么呢?好的文本控件. 我希望文本控件能实现的功能: 纯正的文本控件 文字随意 ...

最新文章

  1. python【数据结构与算法】从一个例子引入动态规划❤️
  2. Codeforces Round #713 (Div. 3)
  3. VS C# DateTimePicker()的小技巧
  4. Linux内核线程kernel thread详解--Linux进程的管理与调度
  5. python 函数例子_Python3函数之例子
  6. linux c++编译问题和虚拟机网络通信
  7. Zabbix触发器和监控项设置时间范围.
  8. Linux下设置定期执行脚本
  9. 【人脸识别】基于matlab GUI SVM和PCA人脸识别【含Matlab源码 369期】
  10. 余晨:我终于采访到了马斯克,他是个腼腆的钢铁侠
  11. LoadRunner 压力测试
  12. E71(S60 3rd)通话录音软件 -终极录音- 的用法
  13. html 小游戏 俄罗斯方块
  14. 各个版本Microsoft Visual C++运行库下载
  15. 【转】BAT机器学习面试1000题系列(1~50)
  16. Kahan's summation Formula
  17. updated beforeUpdate() Updated() 生命周期-销毁阶段 vue的nextTick@stage3---week2--day4-1
  18. TiDB 在汽车之家818台网互动项目中的应用
  19. 边伯贤计算机系文,EXO◆『150920|搬文』边伯贤反攻记【中长/甜】
  20. matlab矩阵乘法运算结果不对,矩阵里乘法使用错误?

热门文章

  1. JavaScript数据结构——字典(Dictionary)
  2. ES6——let、const和var的用法和区别
  3. 零基础带你学习MySQL—字符串相关的函数(十三)
  4. 利息高的贷款通过率会高一些吗?
  5. 路由器连接久点就慢下来了,怎么回事?
  6. 现在开始全职跑滴滴,你怎么看?
  7. 如何改变炒股频繁交易的毛病?
  8. 映日荷花别样红是什么季节,映日荷花别样红的上一句是什么?全诗赏析
  9. 对于大多数的中小微企业,产品是你成功的1.0阶段
  10. 老板看似表面风光,可能还没有员工赚得多