我正在尝试使用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元素?
当前回答
我在这一点上已经很晚了,但我刚刚发现了一个非常酷的方法,用一行代码就可以做到这一点,如果你愿意添加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。使用此属性作为源。
其他回答
我知道我在这方面已经晚了,但我认为您可能会发现这个变体很有用,因为它还允许您在下拉列表中使用描述性字符串而不是枚举常量。为此,使用[System.ComponentModel]装饰每个枚举条目。描述]属性。
例如:
public enum TestEnum
{
[Description("Full test")]
FullTest,
[Description("Incomplete or partial test")]
PartialTest,
[Description("No test performed")]
None
}
这是我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Reflection;
using System.ComponentModel;
using System.Linq.Expressions;
...
private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
Type realModelType = modelMetadata.ModelType;
Type underlyingType = Nullable.GetUnderlyingType(realModelType);
if (underlyingType != null)
{
realModelType = underlyingType;
}
return realModelType;
}
private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } };
public static string GetEnumDescription<TEnum>(TEnum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if ((attributes != null) && (attributes.Length > 0))
return attributes[0].Description;
else
return value.ToString();
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
return EnumDropDownListFor(htmlHelper, expression, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumType = GetNonNullableModelType(metadata);
IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
IEnumerable<SelectListItem> items = from value in values
select new SelectListItem
{
Text = GetEnumDescription(value),
Value = value.ToString(),
Selected = value.Equals(metadata.Model)
};
// If the enum is nullable, add an 'empty' item to the collection
if (metadata.IsNullableValueType)
items = SingleEmptyItem.Concat(items);
return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
}
然后你可以在视图中这样做:
@Html.EnumDropDownListFor(model => model.MyEnumProperty)
**编辑2014年1月23日:微软刚刚发布了MVC 5.1,现在有一个EnumDropDownListFor功能。不幸的是,它似乎不尊重[Description]属性,所以上面的代码仍然有效。请参阅微软MVC 5.1发布说明中的Enum部分。
更新:它支持显示属性[Display(Name = "Sample")],所以你可以使用它。
[更新-刚刚注意到这一点,代码看起来像一个扩展版本的代码:https://blogs.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums/,增加了一些内容。如果是这样,归因似乎是公平的;-)]
所以没有扩展函数,如果你正在寻找简单和容易..这就是我所做的
<%= Html.DropDownListFor(x => x.CurrentAddress.State, new SelectList(Enum.GetValues(typeof(XXXXX.Sites.YYYY.Models.State))))%>
where XXXXX.Sites.YYYY.Models.State是enum
也许做辅助函数更好,但是当时间很短的时候,这将完成工作。
在MVC4中,我会这样做
@Html.DropDownList("RefType", new SelectList(Enum.GetValues(typeof(WebAPIApp.Models.RefType))), " Select", new { @class = "form-control" })
public enum RefType
{
Web = 3,
API = 4,
Security = 5,
FE = 6
}
public class Reference
{
public int Id { get; set; }
public RefType RefType { get; set; }
}
使用Prise的扩展方法来解决获取数字而不是文本的问题。
public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString())
, Name = e.ToString() };
return new SelectList(values, "Id", "Name", enumObj);
}
这里是Martin Faartoft的变种,你可以放自定义标签,这对本地化很好。
public static class EnumHtmlHelper
{
public static SelectList ToSelectList<TEnum>(this TEnum enumObj, Dictionary<int, string> customLabels)
where TEnum : struct, IComparable, IFormattable, IConvertible
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { Id = e, Name = customLabels.First(x => x.Key == Convert.ToInt32(e)).Value.ToString() };
return new SelectList(values, "Id", "Name", enumObj);
}
}
视图中使用:
@Html.DropDownListFor(m => m.Category, Model.Category.ToSelectList(new Dictionary<int, string>() {
{ 1, ContactResStrings.FeedbackCategory },
{ 2, ContactResStrings.ComplainCategory },
{ 3, ContactResStrings.CommentCategory },
{ 4, ContactResStrings.OtherCategory }
}), new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Category)