Je sais je suis en retard à la fête, mais pensé que vous pourriez trouver cette variante utile, comme celle-ci vous permet également d'utiliser des chaînes descriptifs plutôt que de dénombrement des constantes dans la liste déroulante. Pour ce faire, décorer chaque énumération entrée avec un [Système.ComponentModel.Description] l'attribut.
Par exemple:
public enum TestEnum
{
[Description("Full test")]
FullTest,
[Description("Incomplete or partial test")]
PartialTest,
[Description("No test performed")]
None
}
Voici mon code:
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);
}
Ensuite, vous pouvez le faire dans votre vue:
@Html.EnumDropDownListFor(model => model.MyEnumProperty)
Espérons que cela vous aide!
EDITION 2014-JAN-23: Microsoft vient de publier MVC 5.1, qui a maintenant un EnumDropDownListFor fonctionnalité. Malheureusement, il ne semble pas respecter les [Description] l'attribut de sorte que le code ci-dessus est toujours debout. (Voir http://www.asp.net/mvc/overview/releases/mvc51-release-notes#Enum pour Microsoft notes de mise à jour.)
Mise à jour: Il prend en charge la DisplyName attribut [Display(Name = "Sample")]
, donc on peut l'utiliser.
[Mise à jour - juste remarqué cela, et le code ressemble à une version étendue de la code ici: http://blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums.aspxavec un couple d'ajouts. Si oui, l'attribution semble juste ;-)]