[Asp.Net Mvc] 我的下拉列表扩展

一、思考

      之前读了一篇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>

  先看一下效果图吧

[Asp.Net Mvc] 我的下拉列表扩展

  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 

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

你可能感兴趣的:(asp.net)