在ASP.NET MVC中使用“RadioButtonList”和“CheckBoxList”
2012-03-16 10:11
1056 查看
在《为HtmlHelper添加一个RadioButtonList扩展方法》中我通过对HtmlHelper和HtmlHelper<Model>的扩展使我们可以采用”RadioButtonList”的方式对一组类型为“radio”的<input>元素进行操作。昨天对对此进行了一些改进,并将“CheckBoxList”的功能添加进来。[源代码从这里下载]
通过独立的组件对绑定到ListControl(ASP.NET Web Form的说法)的列表进行单独管理;
自动地调用上面这个组件获取列表信息进行相关Html的生成;
支持ASP.NET MVC原生的Model Binding。
[/code]
上述三个属性分别代表CodeManager这个独立组件维护的三个列表,CodeManager和代表列表选项的CodeDescription定义如下:
[/code]
在默认的HomeController中,我们定义了如下两个Index方法,它们分别用于测试出栈数据(Model->UI)入栈数据(UI-〉Model)的绑定。
[/code]
下面是Index操作对应的View的定义,这是一个Model类型为Person的强类型View。对于Person的三个基于列表的属性,我们分别调用了自定义的扩展方法RadioButtonListFor和CheckBoxListFor进行了绑定。方法的最后两个参数分别代表通过CodeManager维护的列表的组别(Gender、MaritalStatus和Country),和同组RadioButton和CheckBox布局方向(水平或者纵向)。
[/code]
下面是最终呈现出来的效果:
[/code]
ListControlUtil中生成相关Html的逻辑定义如下:
[/code]
通过对HtmlHelper扩展简化“列表控件”的绑定
为HtmlHelper添加一个RadioButtonList扩展方法
在ASP.NET MVC中使用“RadioButtonList”和“CheckBoxList”
一、有何特别之处?
和我的很多文章一样,旨在提供一种大体的解决方案,本解决方案旨在解决如下一些问题:通过独立的组件对绑定到ListControl(ASP.NET Web Form的说法)的列表进行单独管理;
自动地调用上面这个组件获取列表信息进行相关Html的生成;
支持ASP.NET MVC原生的Model Binding。
二、实例演示
我们还是以《为HtmlHelper添加一个RadioButtonList扩展方法》例子来演示RadioButtonList和CheckBoxList用法。下面是代表个人信息同时作为Model的Person类型,Gender、MaritalStatus 和Country分别代表性别、婚姻状况和国籍(这里支持多国籍)。[code] public class Person { public string Name { get; set; } public string Gender { get; set; } [Display(Name = "Marital Status")] public string MaritalStatus { get; set; } public string[] Country { get; set; } }
[/code]
上述三个属性分别代表CodeManager这个独立组件维护的三个列表,CodeManager和代表列表选项的CodeDescription定义如下:
[code] public class CodeDescription { public string Code { get; set; } public string Description { get; set; } public string Category{get;set;} public CodeDescription(string code, string description, string category) { this.Code = code; this.Description = description; this.Category = category; } } public static class CodeManager { private static CodeDescription[] codes = new CodeDescription[] { new CodeDescription("M","Male","Gender"), new CodeDescription("F","Female","Gender"), new CodeDescription("S","Single","MaritalStatus"), new CodeDescription("M","Married","MaritalStatus"), new CodeDescription("CN","China","Country"), new CodeDescription("US","Unite States","Country"), new CodeDescription("UK","Britain","Country"), new CodeDescription("SG","Singapore","Country") }; public static Collection<CodeDescription> GetCodes(string category) { Collection<CodeDescription> codeCollection = new Collection<CodeDescription>(); foreach(var code in codes.Where(code=>code.Category == category)) { codeCollection.Add(code); } return codeCollection; } }
[/code]
在默认的HomeController中,我们定义了如下两个Index方法,它们分别用于测试出栈数据(Model->UI)入栈数据(UI-〉Model)的绑定。
[code] public class HomeController : Controller { public ActionResult Index() { return View(new Person { Name = "Foo", Gender = "M", MaritalStatus = "S", Country = new string[]{"CN","US"} }); } [HttpPost] public ActionResult Index(Person person) { return this.View(person); } }
[/code]
下面是Index操作对应的View的定义,这是一个Model类型为Person的强类型View。对于Person的三个基于列表的属性,我们分别调用了自定义的扩展方法RadioButtonListFor和CheckBoxListFor进行了绑定。方法的最后两个参数分别代表通过CodeManager维护的列表的组别(Gender、MaritalStatus和Country),和同组RadioButton和CheckBox布局方向(水平或者纵向)。
[code] @using System.Web.UI.WebControls @model Person @{ ViewBag.Title = "Index"; } @using (Html.BeginForm()) { <table id="container"> <tr> <td class="label">@Html.LabelFor(m => m.Name):</td> <td>@Html.EditorFor(m => m.Name)</td> </tr> <tr> <td class="label">@Html.LabelFor(m => m.Gender):</td> <td>@Html.RadioButtonListFor(m => m.Gender, "Gender")</td> </tr> <tr> <td class="label">@Html.LabelFor(m => m.MaritalStatus):</td> <td>@Html.RadioButtonListFor(m => m.MaritalStatus, "MaritalStatus")</td> </tr> <tr> <td class="label">@Html.LabelFor(m => m.Country):</td> <td>@Html.CheckBoxListFor(m => m.Country, "Country", RepeatDirection.Vertical)</td> </tr> <tr> <td colspan="2"><input type="submit" value="Save" /></td> </tr> </table> }
[/code]
下面是最终呈现出来的效果:
三、两组扩展方法具体实现
现在我们简单地来看看RadioButtonList/RadioButtonListFor和CheckBoxList/CheckBoxListFor这两组扩展方法的实现。我们通过CodeManager得到列表集合,通过HtmlHelper结合 ModelMetadata得到当前数据,最终借助于ListControlUtil的GenerateHtml生成相关的Html。[code] public static class ListControlExtensions { public static MvcHtmlString RadioButtonList(this HtmlHelper htmlHelper, string name, string codeCategory, RepeatDirection repeatDirection = RepeatDirection.Horizontal) { var codes = CodeManager.GetCodes(codeCategory); return ListControlUtil.GenerateHtml(name, codes, repeatDirection,"radio",null); } public static MvcHtmlString RadioButtonListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string codeCategory, RepeatDirection repeatDirection = RepeatDirection.Horizontal) { var codes = CodeManager.GetCodes(codeCategory); ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData); string name = ExpressionHelper.GetExpressionText(expression); string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); return ListControlUtil.GenerateHtml(fullHtmlFieldName, codes, repeatDirection, "radio", metadata.Model); } public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, string codeCategory, RepeatDirection repeatDirection = RepeatDirection.Horizontal) { var codes = CodeManager.GetCodes(codeCategory); return ListControlUtil.GenerateHtml(name, codes, repeatDirection, "checkbox", null); } public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string codeCategory, RepeatDirection repeatDirection = RepeatDirection.Horizontal) { var codes = CodeManager.GetCodes(codeCategory); ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData); string name = ExpressionHelper.GetExpressionText(expression); string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); return ListControlUtil.GenerateHtml(fullHtmlFieldName, codes, repeatDirection, "checkbox", metadata.Model); } }
[/code]
ListControlUtil中生成相关Html的逻辑定义如下:
[code] public static class ListControlUtil { public static MvcHtmlString GenerateHtml(string name, Collection<CodeDescription> codes, RepeatDirection repeatDirection, string type, object stateValue) { TagBuilder table = new TagBuilder("table"); int i = 0; bool isCheckBox = type == "checkbox"; if (repeatDirection == RepeatDirection.Horizontal) { TagBuilder tr = new TagBuilder("tr"); foreach (var code in codes) { i++; string id = string.Format("{0}_{1}", name, i); TagBuilder td = new TagBuilder("td"); bool isChecked = false; if (isCheckBox) { IEnumerable<string> currentValues = stateValue as IEnumerable<string>; isChecked = (null != currentValues && currentValues.Contains(code.Code)); } else { string currentValue = stateValue as string; isChecked = (null != currentValue && code.Code == currentValue); } td.InnerHtml = GenerateRadioHtml(name, id, code.Description, code.Code, isChecked,type); tr.InnerHtml += td.ToString(); } table.InnerHtml = tr.ToString(); } else { foreach (var code in codes) { TagBuilder tr = new TagBuilder("tr"); i++; string id = string.Format("{0}_{1}", name, i); TagBuilder td = new TagBuilder("td"); bool isChecked = false; if (isCheckBox) { IEnumerable<string> currentValues = stateValue as IEnumerable<string>; isChecked = (null != currentValues && currentValues.Contains(code.Code)); } else { string currentValue = stateValue as string; isChecked = (null != currentValue && code.Code == currentValue); } td.InnerHtml = GenerateRadioHtml(name, id, code.Description, code.Code, isChecked, type); tr.InnerHtml = td.ToString(); table.InnerHtml += tr.ToString(); } } return new MvcHtmlString(table.ToString()); } private static string GenerateRadioHtml(string name, string id, string labelText, string value, bool isChecked, string type) { StringBuilder sb = new StringBuilder(); TagBuilder label = new TagBuilder("label"); label.MergeAttribute("for", id); label.SetInnerText(labelText); TagBuilder input = new TagBuilder("input"); input.GenerateId(id); input.MergeAttribute("name", name); input.MergeAttribute("type", type); input.MergeAttribute("value", value); if (isChecked) { input.MergeAttribute("checked", "checked"); } sb.AppendLine(input.ToString()); sb.AppendLine(label.ToString()); return sb.ToString(); } }
[/code]
通过对HtmlHelper扩展简化“列表控件”的绑定
为HtmlHelper添加一个RadioButtonList扩展方法
在ASP.NET MVC中使用“RadioButtonList”和“CheckBoxList”
相关文章推荐
- 在ASP.NET MVC中使用“RadioButtonList”和“CheckBoxList”
- ASP.NET MVC 中使用“RadioButtonList”和“CheckBoxList”
- ASP.NET的checkboxlist,RadioButtonList,FileUpload,image控件的综合使用
- ASP.NET MVC 3 CheckBoxList 的使用
- ASP.NET MVC 3 CheckBoxList 的使用
- ASP.NET MVC 3.0 知识记要(2)【RadioButtonList、CheckBoxList】
- ASP.NET MVC 3 CheckBoxList 的使用
- ASP.NET MVC 3 CheckBoxList 的使用
- ASP.NET MVC 3 CheckBoxList 的使用
- ASP.NET中 RadioButtonList(单选按钮组),CheckBoxList(复选框组),DropDownList(下拉框),ListBox(列表框),BulletedList(无序列表)的使用前台绑定
- ASP.NET中CheckBoxList复选框列表控件详细使用方法
- ASP.NET MVC 5使用X.PagedList.Mvc进行分页教程(PagedList.Mvc)
- 在Asp.Net MVC中使用ModelBinding构造Array、List、Collection以及Dictionary
- asp.net MVC中使用Html.Checkbox提示该字符串未被识别为有效的布尔值错误的解决方法
- asp.net mvc中构建htmlHelper的checkboxlist
- Asp.net MVC 使用PagedList(新的已更名 为X.PagedList.Mvc) 分页
- Asp.net服务器端控件CheckBoxList的使用心得
- Asp.net MVC、Extjs(运用Linq to SQL和List泛型)批量更新、删除、打印(使用CKEditor)、导出Excel
- ASP.NET服务器端控件RadioButtonList,DropDownList,CheckBoxList的取值、赋值用法
- asp.net中repeater嵌套CheckBoxList,RadioButtonList来完成投票