在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、思考 之前读了一篇Artech大神写的关于列表控件绑定的博文[ASP.NET MVC]通过对HtmlHelper扩展简化“列表控件”的绑定,很受益。 不过在具体的使用中往往会遇到一些问题,就是列表中的数据往往不是我们预先能够知道的,或者说填充列表的数据一般都是从数据库里面读取得来的,这个时候怎么做呢? 二、假设的场景现在我们要做一个简单的新闻系统,只考虑新闻和类别两个实体。下面给出新闻和类别的类定义: /// <summary> /// 新闻类别 /// </summary> public class Category { [DisplayName("Id")] public Int32 Id { get; set; } [DisplayName("名称")] public String OfName { get; set; } [DisplayName("标签")] public String Label { get; set; } } /// <summary> /// 新闻 /// </summary> public class OurNews { public Guid Id { get; set; } [DisplayName("分类")] public Int32 CategoryId { get; set; } [DisplayName("标题")] public String Title { get; set; } [DisplayName("内容")] public String Content { get; set; } } 先预先添加一些新闻类别的数据,在contreller的构造函数中添加。并添加一个“AddNews”的Action: private List<Category> prevCategories; public HomeController() { prevCategories = new List<Category>() { new Category{ Id = 0, OfName="生活", Label="SH"}, new Category{ Id = 1, OfName="体育", Label="TY"}, new Category{ Id = 2, OfName="学习", Label="XX"} }; } public ActionResult AddNews() { this.ViewBag.prevCategories = this.prevCategories; // 新闻类别数据,用于填充下拉列表的数据 return View(); } 然后转到添加新闻的视图,在添加新闻时,我们一般都会把分类那一栏做成一个下拉列表,而我们一般做的都是构建一个List<SelectListItem>,然后直接调用Html.DropDownList即可;然而我们为了视图的整洁经常会做去扩展Html.DropDownList这个方法,就如下面给出的视图代码。1是一般的方法,2是经过扩展之后的方法。下面是两种方式书写的代码: @{ var prevCategories = this.ViewBag.prevCategories as List<Category>;} <div class="editor-label"> @Html.LabelFor(model => model.CategoryId) </div> <div class="editor-field"> <table> <tr> <td>1.一般流</td> @{var items = new List<SelectListItem>(); foreach (var category in prevCategories) { items.Add(new SelectListItem { Text = category.OfName, Value = category.Id.ToString() }); } } <td>@Html.DropDownList("Id",items,"=请选择=")</td> </tr> <tr> <td rowspan="2">2.扩展流</td> <td>@(Html.DropDownList<Category>("Id", "OfName", "Id", prevCategories, "=请选择=", new { }))</td> @*反射*@ </tr> <tr> <td>@(Html.DropDownList<Category>("Id", c => c.OfName,c=>c.Id.ToString(), prevCategories, "=请选择=", new { }))</td> @*委托*@ </tr> </table> </div> 先看一下效果图吧 DropDownList的扩展用了两种不同的方法,所以有两种写法。现在开始步入正题了 第1种方法的不好之处呢就是看起来有些冗余了,是不是每一次遇到这种情况都要构建List<SelectListItem>这么来一下。当然没这个必要了,那就用第二种方式吧,扩展DropDownList。 三、扩展DropDownList扩展DropDownList的目的就是不想再重复构建List<SelectListItem>类,那就把List<SelectListItem>的构建放到扩展方法中来,构建时遇到的问题就是如何从获取数据源类型和填充的字段,由于在数据源类型是可变的,所以就需要用到泛型,用了泛型之后对于字段的填充问题出现了,解决的方法有两种,一个就是用到反射,另外一个就是用到委托 public static class DropDownListExtensions { /// <summary> /// 反射 /// </summary> public static MvcHtmlString DropDownList<TEntity>(this HtmlHelper html, String name, String textField, String valueField, IList<TEntity> entityList, String optionLabel, object htmlAttributes) { var items = new List<SelectListItem>(); var type = typeof(TEntity); foreach (var entity in entityList) { var textPropety = type.GetProperty(textField); var valuePropety = type.GetProperty(valueField); items.Add(new SelectListItem { Text = textPropety.GetValue(entity, null).ToString(), Value = valuePropety.GetValue(entity, null).ToString() }); } return html.DropDownList(name, items, optionLabel, htmlAttributes); } /// <summary> /// 委托 /// </summary> public static MvcHtmlString DropDownList<TEntity>(this HtmlHelper html, String name, Func<TEntity, String> textField, Func<TEntity, String> valueField, IList<TEntity> entityList, String optionLabel, object htmlAttributes) { var items = new List<SelectListItem>(); foreach (var entity in entityList) { items.Add(new SelectListItem { Text = textField(entity), Value = valueField(entity) }); } return html.DropDownList(name, items, optionLabel, htmlAttributes); } } 四、总结感觉道理说得不是很清楚,但是用的时候还是觉得蛮方便的,所以就分享给大家了。 示例程序:点击这里下载
作者:Xanthondont 出处:http://www.cnblogs.com/hbq-fczzw/archive/2012/04/18/2455813.html 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 |
请发表评论