Как добавить -Выбрать что-нибудь из DropDownList, созданного из перечисления - PullRequest
0 голосов
/ 04 октября 2011

Я подписался на этот блог , чтобы иметь возможность создавать DropDownLists из нескольких перечислений, которые нам нужны в наших ViewModels.

Пока мой код выглядит так:

public static class HtmlDropDownExtensions
{
    private static readonly SelectListItem [] SingleEmptyItem = new[]{new SelectListItem{Text = string.Empty, Value = string.Empty}};

public static MvcHtmlString EnumDropDownList<TEnum>(this HtmlHelper htmlHelper, string modelPropertyName, TEnum selectedValue)
{
    Type baseEnumType = Enum.GetUnderlyingType(typeof(TEnum));
    IEnumerable<TEnum> values = Enum.GetValues(typeof (TEnum)).Cast<TEnum>();
    IEnumerable<SelectListItem> items = GetSelectListItems(values, selectedValue, baseEnumType);

    return htmlHelper.DropDownList(modelPropertyName, items);
}

public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    Type enumType = GetNonNullableModelType(metadata);

    Type baseEnumType = Enum.GetUnderlyingType(enumType);
    IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
    IEnumerable<SelectListItem> items = GetSelectListItems(values, metadata.Model, baseEnumType);

    if (metadata.IsNullableValueType)
        items = SingleEmptyItem.Concat(items);

    return htmlHelper.DropDownListFor(expression, items);
}

private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
    Type realModelType = modelMetadata.ModelType;

    Type underlyingType = Nullable.GetUnderlyingType(realModelType);
    if(underlyingType != null)
        realModelType = underlyingType;

    return realModelType;
}

private static IEnumerable<SelectListItem> GetSelectListItems<TEnum>(IEnumerable<TEnum> values, object selectedValue, Type underlyingType)
{
    return from value in values
           select new SelectListItem
           {
               Text = value.ToString(),
               Value = Convert.ChangeType(value, underlyingType).ToString(),
               Selected = (value.Equals(selectedValue))
           };
    }
}

Теперь мне нужно иметь возможность иметь первую опцию, которая предлагает пользователю выбрать опцию, быть пустой или невыбранной или что-то еще, поскольку поля являются обязательными и не может быть никаких значений по умолчанию.

Обновление: Я думал, что, возможно, метод «EnumDropDownList» мог бы добавить пустой SelectListItem перед созданием DropDownList и возвращением строки. Я еще не пробовал это, но я думаю, что будет ошибка, когда ядро ​​MVC пытается связать это с ViewModel, так как будет невозможно проанализировать это значение в свойстве enum ViewModel.

Спасибо за помощь.

1 Ответ

0 голосов
/ 04 октября 2011

На самом деле все уже реализовано:

if (metadata.IsNullableValueType)
    items = SingleEmptyItem.Concat(items);

Если свойство модели имеет тип Nullable<YourEnum>, этот код добавит элемент по умолчанию в начале DropDownList.

Однако, если свойство не допускает пустых значений, значение по умолчанию не будет отображаться. И это правильное поведение - пользователь должен что-то ввести и не должен видеть никаких элементов по умолчанию.

Если вы хотите изменить текст значения по умолчанию, перейдите к определению SingleEmptyItem:

private static readonly SelectListItem [] SingleEmptyItem = new[]{new SelectListItem{Text = "Your text here", Value = string.Empty}};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...