当我们使用@Html.DropdownList()时,实际上使用了Razor引擎自带的helper来生成一段html代码,先来看接受的构造方法
public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name); public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList); public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, string optionLabel); public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes); public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes); public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel); public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes); public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes);
参数name表示接受ViewData[“name”]的数据,此数据必须支持IEnumerable<SelectListItem>接口,且必须提供;
参数optionLable表示未选中任何项时默认显示的字段(不提供则默认选中第一项);
参数htmlAttributes用以向生成的select添加各项属性,可以用object和名值对的方式给出;
参数selectList也是IEnumerable<SelectListItem>接口,暂时不知道作用是什么,目前知道当提供了此参数时,ViewData[“name”]所提供的数据会被覆盖,只有selectList的数据起效
public class SelectListItem { public SelectListItem(); public bool Selected { get; set; } public string Text { get; set; } public string Value { get; set; } }
SelectListItem非常简单,一共3个属性,string类型的Value和Text对应select的value和text,bool类型的selected指定当前项是否选中
//controller代码 List<SelectListItem> selectOption = new List<SelectListItem>(); selectOption.Add(new SelectListItem { Value = "1", Text = "一", Selected = true }); selectOption.Add(new SelectListItem { Value = "2", Text = "二" }); ViewData["selectOption"] = selectOption;
//view代码 @(Html.DropDownList("selectOption", "请选择"))
这样是两个option,默认选中第一个,生成的select的name属性和id属性与ViewData名相同,为”selectOption“
之前提到参数selectList能够覆盖参数name所提供的数据,此种情况下,option被覆盖,但是name属性仍然由参数name决定
//controller添加selectOption2 List<SelectListItem> selectOption2 = new List<SelectListItem>(); selectOption2.Add(new SelectListItem { Value = "3", Text = "三" }); selectOption2.Add(new SelectListItem { Value = "4", Text = "四" }); ViewData["selectOption2"] = selectOption2;
//view修改为 @(Html.DropDownList("selectOption", @ViewData["selectOption2"] as IEnumerable<SelectListItem>, "请选择"))
此时,selectList2的数据覆盖了selectList的数据,而select的id和name属性仍为”selectOption“
这个参数有两种形式,一种是直接写在html页中
@(Html.DropDownList("selectOption", null, "请选择", new { name = "mySelect", id = "mySelect" }))
注意由参数name提供的name属性无法被覆盖,id被正确覆盖为”mySelect“,而name仍为”selectOption“,在提交表单request取数据时需要注意;并且原型中所有提供了htmlAttributes参数的重载都需要selectList参数,同样不知道为什么
此时是以object方式直接在view提供htmlAttributes参数,当然也可以在controller中定义一个object变量通过ViewData传给view
另一种方式是提供支持IDictionary<string,object>接口的变量
//controller代码 Dictionary<string, object> selectAttr = new Dictionary<string, object>(); selectAttr.Add("id", "mySelect"); selectAttr.Add("style", "width:300px"); ViewData["selectAttr"] = selectAttr;
//view代码 @(Html.DropDownList("selectOption", null, "请选择", @ViewData["selectAttr"] as IDictionary<string, object>))
.net提供了SelectList类型用以方便的将实体类转换为IEnumerable<SelectListItem>类型,接受的构造方法如下
public SelectList(IEnumerable items); public SelectList(IEnumerable items, object selectedValue); public SelectList(IEnumerable items, string dataValueField, string dataTextField); public SelectList(IEnumerable items, string dataValueField, string dataTextField, object selectedValue);
首先是支持IEnumerable接口的参数items,dataValueField和dataTextField用以指明充当value和text的字段,selectedValue表示默认选中值
例如,
public class Student { public Student(int id,string name,int age) { Id = id; Name = name; Age = age; } public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }
List<Student> listStudent = new List<Student> { new Student(1,"Tom",18), new Student(2,"Jerry",19), new Student(3,"John",20) }; SelectList selectList = new SelectList(listStudent, "Id", "Name", 2);
@(Html.DropDownList("selectList", "请选择"))
这样就能方便的将实体类中的数据映射到select控件中,需要注意的是,若指定选中的value不存在,系统不会报错,而是会选中默认值;即使实体类中只有2个字段,也必须指明value和text参数,系统无法自动识别
枚举类型的值+描述模式跟select控件的value+text模式很契合,使用枚举类型来维护select控件的option一些情况下会很方便,下面来写一个方法把Enum类型转换为SelectList类型
enum Date { [Description("年")] year, [Description("月")] month, [Description("日")] day }
上面的枚举类型,未指明值则默认year=0,month=1,day=2,int类型的值0,1,2将会作为value传到前端,而不是year,month,day
public class EnumItem { public int Value { get; set; } public string Text { get; set; } }
建立实体类,以List<EnumItem>类型接受Enum的值
List<EnumItem> listEnum = new List<EnumItem>(); listEnum = (from Enum value in Enum.GetValues(typeof(Date)) select new EnumItem { Value = Convert.ToInt32(value), Text = ((DescriptionAttribute)value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), true)[0]).Description }).ToList(); SelectList selectList = new SelectList(listEnum, "Value", "Text");
这样就能成功将Enum类型的数据映射到select控件中,那么当接收前端返回的选中值为string类型的0,1,2,如何对应到相应的description呢,Enum提供的Parse方法可以方便的做到
Enum selectedValue=(Date)Enum.Parse(typeof(Date), postedValue); string selectedText = ((DescriptionAttribute)selectedValue.GetType().GetField(selectedValue.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), true)[0]).Description;
原文:http://www.cnblogs.com/fxMorris/p/5122780.html