Tôi biết tôi đến bữa tiệc muộn, nhưng nghĩ rằng bạn có thể thấy biến thể này hữu ích, vì biến thể này cũng cho phép bạn sử dụng các chuỗi mô tả thay vì các hằng số liệt kê trong trình đơn thả xuống. Để thực hiện việc này, hãy trang trí mỗi mục liệt kê bằng thuộc tính [System.ComponentModel.Description].
Ví dụ:
public enum TestEnum
{
[Description("Full test")]
FullTest,
[Description("Incomplete or partial test")]
PartialTest,
[Description("No test performed")]
None
}
Đây là mã của tôi:
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);
}
Sau đó, bạn có thể làm điều này trong quan điểm của bạn:
@Html.EnumDropDownListFor(model => model.MyEnumProperty)
Hy vọng điều này sẽ giúp bạn!
** EDIT 2014-JAN-23: Microsoft vừa phát hành MVC 5.1, hiện có tính năng EnumDropDownListFor. Đáng buồn thay, nó dường như không tôn trọng thuộc tính [Mô tả] vì vậy đoạn mã trên vẫn đứng. Phần Enum trong ghi chú phát hành của Microsoft cho MVC 5.1.
Cập nhật: Mặc dù vậy, nó hỗ trợ thuộc tính Display[Display(Name = "Sample")]
, vì vậy người ta có thể sử dụng thuộc tính Display .
[Cập nhật - chỉ cần chú ý điều này và mã trông giống như một phiên bản mở rộng của mã ở đây: https://bloss.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a- dropdownlist-helper-for-enums / , với một vài bổ sung. Nếu vậy, ghi công có vẻ công bằng ;-)]