在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在《为HtmlHelper添加一个RadioButtonList扩展方法》中我通过对HtmlHelper和HtmlHelper<Model>的扩展使我们可以采用”RadioButtonList”的方式对一组类型为“radio”的<input>元素进行操作。昨天对对此进行了一些改进,并将“CheckBoxList”的功能添加进来。[源代码从这里下载] 和我的很多文章一样,旨在提供一种大体的解决方案,本解决方案旨在解决如下一些问题:
二、实例演示我们还是以《为HtmlHelper添加一个RadioButtonList扩展方法》例子来演示RadioButtonList和CheckBoxList用法。下面是代表个人信息同时作为Model的Person类型,Gender、MaritalStatus 和Country分别代表性别、婚姻状况和国籍(这里支持多国籍)。 1: public class Person 2: {
3: public string Name { get; set; } 4: public string Gender { get; set; } )]
6: public string MaritalStatus { get; set; } 7: public string[] Country { get; set; } 8: }
上述三个属性分别代表CodeManager这个独立组件维护的三个列表,CodeManager和代表列表选项的CodeDescription定义如下: 1: public class CodeDescription 2: {
3: public string Code { get; set; } 4: public string Description { get; set; } 5: public string Category{get;set;} 6:
7: public CodeDescription(string code, string description, string category) 8: {
9: this.Code = code; 10: this.Description = description; 11: this.Category = category; 12: }
13: }
14: public static class CodeManager 15: {
16: private static CodeDescription[] codes = new CodeDescription[] 17: {
),
),
),
),
),
),
),
)
26: };
27: public static Collection<CodeDescription> GetCodes(string category) 28: {
29: Collection<CodeDescription> codeCollection = new Collection<CodeDescription>(); 30: foreach(var code in codes.Where(code=>code.Category == category)) 31: {
32: codeCollection.Add(code);
33: }
34: return codeCollection; 35: }
36: }
在默认的HomeController中,我们定义了如下两个Index方法,它们分别用于测试出栈数据(Model->UI)入栈数据(UI-〉Model)的绑定。 1: public class HomeController : Controller 2: {
3: public ActionResult Index() 4: {
} });
6: }
7: [HttpPost]
8: public ActionResult Index(Person person) 9: {
10: return this.View(person); 11: }
12: }
下面是Index操作对应的View的定义,这是一个Model类型为Person的强类型View。对于Person的三个基于列表的属性,我们分别调用了自定义的扩展方法RadioButtonListFor和CheckBoxListFor进行了绑定。方法的最后两个参数分别代表通过CodeManager维护的列表的组别(Gender、MaritalStatus和Country),和同组RadioButton和CheckBox布局方向(水平或者纵向)。 1: @using System.Web.UI.WebControls
2: @model Person
3: @{
下面是最终呈现出来的效果: 三、两组扩展方法具体实现现在我们简单地来看看RadioButtonList/RadioButtonListFor和CheckBoxList/CheckBoxListFor这两组扩展方法的实现。我们通过CodeManager得到列表集合,通过HtmlHelper结合 ModelMetadata得到当前数据,最终借助于ListControlUtil的GenerateHtml生成相关的Html。 1: public static class ListControlExtensions 2: {
3: public static MvcHtmlString RadioButtonList(this HtmlHelper htmlHelper, string name, string codeCategory, RepeatDirection repeatDirection = RepeatDirection.Horizontal) 4: {
5: var codes = CodeManager.GetCodes(codeCategory);
,null);
7: }
8: public static MvcHtmlString RadioButtonListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string codeCategory, RepeatDirection repeatDirection = RepeatDirection.Horizontal) 9: {
10: var codes = CodeManager.GetCodes(codeCategory);
11: ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
12: string name = ExpressionHelper.GetExpressionText(expression); 13: string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); , metadata.Model);
15: }
16:
17: public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, string codeCategory, RepeatDirection repeatDirection = RepeatDirection.Horizontal) 18: {
19: var codes = CodeManager.GetCodes(codeCategory);
, null);
21: }
22: public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string codeCategory, RepeatDirection repeatDirection = RepeatDirection.Horizontal) 23: {
24: var codes = CodeManager.GetCodes(codeCategory);
25: ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
26: string name = ExpressionHelper.GetExpressionText(expression); 27: string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); , metadata.Model);
29: }
30: }
ListControlUtil中生成相关Html的逻辑定义如下: 1: public static class ListControlUtil 2: {
3: public static MvcHtmlString GenerateHtml(string name, Collection<CodeDescription> codes, RepeatDirection repeatDirection, string type, object stateValue) 4: {
);
6: int i = 0; ;
8: if (repeatDirection == RepeatDirection.Horizontal) 9: {
);
11: foreach (var code in codes) 12: {
13: i++;
, name, i);
);
16:
17: bool isChecked = false; 18: if (isCheckBox) 19: {
20: IEnumerable<string> currentValues = stateValue as IEnumerable<string>; 21: isChecked = (null != currentValues && currentValues.Contains(code.Code)); 22: }
23: else 24: {
25: string currentValue = stateValue as string; 26: isChecked = (null != currentValue && code.Code == currentValue); 27: }
28:
29: td.InnerHtml = GenerateRadioHtml(name, id, code.Description, code.Code, isChecked,type);
30: tr.InnerHtml += td.ToString();
31: }
32: table.InnerHtml = tr.ToString();
33: }
34: else 35: {
36: foreach (var code in codes) 37: {
);
39: i++;
, name, i);
);
42:
43: bool isChecked = false; 44: if (isCheckBox) 45: {
46: IEnumerable<string> currentValues = stateValue as IEnumerable<string>; 47: isChecked = (null != currentValues && currentValues.Contains(code.Code)); 48: }
49: else 50: {
51: string currentValue = stateValue as string; 52: isChecked = (null != currentValue && code.Code == currentValue); 53: }
54:
55: td.InnerHtml = GenerateRadioHtml(name, id, code.Description, code.Code, isChecked, type);
56: tr.InnerHtml = td.ToString();
57: table.InnerHtml += tr.ToString();
58: }
59: }
60: return new MvcHtmlString(table.ToString()); 61: }
62:
63: private static string GenerateRadioHtml(string name, string id, string labelText, string value, bool isChecked, string type) 64: {
65: StringBuilder sb = new StringBuilder(); 66:
);
, id);
69: label.SetInnerText(labelText);
70:
);
72: input.GenerateId(id);
, name);
, type);
, value);
76: if (isChecked) 77: {
);
79: }
80: sb.AppendLine(input.ToString());
81: sb.AppendLine(label.ToString());
82: return sb.ToString(); 83: }
84: }
通过对HtmlHelper扩展简化“列表控件”的绑定 http://artech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 |
请发表评论