Ниже приведено расширение к HtmlHelper. Он очень похож на расширение EnumDropDownListFor из ASP.NET, но он сортирует SelectListItem с помощью отображаемого имени элемента. У этого есть наводящее на размышления имя: SortedEnumDropDownListFor не конфликтует с исходным расширением.
/// <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;
}
Если вы не хотите возиться с неактивной intitia пункт, просто построить перегрузки, как это:
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;
}
И вы хорошо идти. Я надеюсь, что это помогает.
Вы можете скопировать исходный код MVC для 'EnumDropDownListFor' [здесь] (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/SelectExtensions.cs) и [здесь] (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/EnumHelper.cs) и изменить подпись, чтобы включить параметр, представляющий собой набор исключенных значений, а затем в 'EnumHelper .GetSelectList() ', игнорировать элементы, которые находятся в исключенных значениях. –