我正在尝试使用Html。下拉列表扩展方法,但不知道如何与枚举一起使用它。
假设我有一个这样的枚举:
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
我如何去创建一个下拉与这些值使用Html。下拉列表扩展方法?
或者我最好的办法是简单地创建一个for循环并手动创建Html元素?
我正在尝试使用Html。下拉列表扩展方法,但不知道如何与枚举一起使用它。
假设我有一个这样的枚举:
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
我如何去创建一个下拉与这些值使用Html。下拉列表扩展方法?
或者我最好的办法是简单地创建一个for循环并手动创建Html元素?
当前回答
我做了以下工作,并取得了成功:
在view.cshtml中:
@ model MyModel.cs
@Html.EnumDropDownListFor(m=>m.MyItemType )
模型中: MyModel.cs
MyItemType {get;设置;}
其他回答
扩展Prise和Rune的答案,如果你想让你的选择列表项的value属性映射到枚举类型的整数值,而不是字符串值,使用以下代码:
public static SelectList ToSelectList<T, TU>(T enumObj)
where T : struct
where TU : struct
{
if(!typeof(T).IsEnum) throw new ArgumentException("Enum is required.", "enumObj");
var values = from T e in Enum.GetValues(typeof(T))
select new {
Value = (TU)Convert.ChangeType(e, typeof(TU)),
Text = e.ToString()
};
return new SelectList(values, "Value", "Text", enumObj);
}
与其将每个Enumeration值视为TEnum对象,不如将其视为对象,然后将其强制转换为整数以获得未装箱的值。
注意: 我还添加了一个泛型类型约束,以限制该扩展只能用于结构(Enum的基类型)的类型,以及一个运行时类型验证,以确保传入的结构确实是Enum。
更新10/23/12: 为底层类型添加了泛型类型参数,并修复了影响. net 4+的非编译问题。
在ASP。NET MVC 5.1,他们添加了EnumDropDownListFor()助手,所以不需要自定义扩展:
模型:
public enum MyEnum
{
[Display(Name = "First Value - desc..")]
FirstValue,
[Display(Name = "Second Value - desc...")]
SecondValue
}
观点:
@Html.EnumDropDownListFor(model => model.MyEnum)
使用标签助手(ASP。Net MVC 6):
<select asp-for="@Model.SelectedValue" asp-items="Html.GetEnumSelectList<MyEnum>()">
超文本标记语言DropDownListFor只需要一个IEnumerable,所以Prise的解决方案的替代方案如下。这将允许你简单地写:
@Html.DropDownListFor(m => m.SelectedItemType, Model.SelectedItemType.ToSelectList())
[其中SelectedItemType是ItemTypes类型的模型上的字段,并且您的模型是非空的]
此外,您实际上不需要泛化扩展方法,因为您可以使用enumValue.GetType()而不是typeof(T)。
编辑:集成西蒙的解决方案在这里以及,并包括ToDescription扩展方法。
public static class EnumExtensions
{
public static IEnumerable<SelectListItem> ToSelectList(this Enum enumValue)
{
return from Enum e in Enum.GetValues(enumValue.GetType())
select new SelectListItem
{
Selected = e.Equals(enumValue),
Text = e.ToDescription(),
Value = e.ToString()
};
}
public static string ToDescription(this Enum value)
{
var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
}
更新-我建议使用下面的符文建议,而不是这个选项!
我猜你想要的是下面这样的话:
<select name="blah">
<option value="1">Movie</option>
<option value="2">Game</option>
<option value="3">Book</option>
</select>
你可以用一个扩展方法来做,如下所示:
public static string DropdownEnum(this System.Web.Mvc.HtmlHelper helper,
Enum values)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("<select name=\"blah\">");
string[] names = Enum.GetNames(values.GetType());
foreach(string name in names)
{
sb.Append("<option value=\"");
sb.Append(((int)Enum.Parse(values.GetType(), name)).ToString());
sb.Append("\">");
sb.Append(name);
sb.Append("</option>");
}
sb.Append("</select>");
return sb.ToString();
}
但这类内容是无法本土化的(游戏邦注:即很难将其翻译成其他语言)。
注意:你需要调用静态方法的枚举实例,即Html.DropdownEnum(ItemTypes.Movie);
也许有一种更优雅的方式来做到这一点,但上面的方法确实有效。
我在这一点上已经很晚了,但我刚刚发现了一个非常酷的方法,用一行代码就可以做到这一点,如果你愿意添加Unconstrained Melody NuGet包(来自Jon Skeet的一个漂亮的小库)。
这个解决方案更好,因为:
它确保(使用泛型类型约束)值确实是一个枚举值(由于Unconstrained Melody) 它避免了不必要的装箱(由于无约束旋律) 它缓存所有的描述,以避免在每个调用上使用反射(由于Unconstrained Melody) 它比其他解决方案的代码更少!
所以,下面是让它工作的步骤:
在包管理器控制台中,“Install-Package UnconstrainedMelody” 在你的模型上添加一个属性,如下所示: //用你的枚举类型替换"YourEnum public IEnumerable<SelectListItem> AllItems { 得到 { 返回Enums.GetValues < YourEnum >()。Select(enumValue => new SelectListItem {Value = enumValue. tostring (), Text = enumValue. getdescription ()}); } }
现在您已经在模型上公开了SelectListItem的列表,您可以使用@Html。下拉列表或@Html。使用此属性作为源。