Di seguito è un'estensione per HtmlHelper. È molto simile all'estensione EnumDropDownListFor di ASP.NET, ma ordina SortListItem dal nome visualizzato dell'oggetto. Ha un nome suggestivo: SortedEnumDropDownListFor per non essere in conflitto con l'estensione originale.
/// <summary>
///
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <typeparam name="TEnum">The type of the value.</typeparam>
/// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
/// <param name="expression">An expression that identifies the object that contains the properties to display</param>
/// <param name="initalValue">The unselected item initial value</param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static MvcHtmlString SortedEnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, string initalValue, object htmlAttributes = null)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumType = GetNonNullableModelType(metadata);
Type baseEnumType = Enum.GetUnderlyingType(enumType);
List<SelectListItem> items = new List<SelectListItem>();
foreach (FieldInfo field in enumType.GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public))
{
string text = field.Name;
string value = Convert.ChangeType(field.GetValue(null), baseEnumType).ToString();
bool selected = field.GetValue(null).Equals(metadata.Model);
foreach (DisplayAttribute displayAttribute in field.GetCustomAttributes(true).OfType<DisplayAttribute>())
{
text = displayAttribute.GetName();
}
items.Add(new SelectListItem
{
Text = text,
Value = value,
Selected = selected
});
}
items = new List<SelectListItem>(items.OrderBy(s => s.Text));
items.Insert(0, new SelectListItem { Text = initalValue, Value = "" });
return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
}
private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
Type realModelType = modelMetadata.ModelType;
Type underlyingType = Nullable.GetUnderlyingType(realModelType);
if (underlyingType != null)
{
realModelType = underlyingType;
}
return realModelType;
}
Se non si vuole perdere tempo con la voce intitia non selezionata, basta costruire un sovraccarico come questo:
public static MvcHtmlString SortedEnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes = null)
{
MvcHtmlString helper = SortedEnumDropDownListFor(htmlHelper, expression, string.Empty, htmlAttributes);
return helper;
}
E tu sei a posto. Spero possa essere d'aiuto.
È possibile copiare il codice sorgente MVC per 'EnumDropDownListFor' [qui] (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/SelectExtensions.cs) e [qui] (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/EnumHelper.cs) e modificare la firma per includere un parametro che è una raccolta di valori esclusi, quindi in 'EnumHelper .GetSelectList() 'metodo, ignora gli elementi che si trovano nei valori esclusi. –