Как я могу преобразовать перечисление в список<SelectListItem>?

У меня есть веб-страница asp.net-mvc, и я хочу показать выпадающий список, основанный на перечислении. Я хочу показать текст каждого элемента перечисления и идентификатор, являющийся значением int, с которым связано перечисление. Есть ли какой-нибудь элегантный способ сделать это преобразование?

8 ответов

Решение

Вы можете использовать LINQ:

Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Select(v => new SelectListItem {
    Text = v.ToString(),
    Value = ((int)v).ToString()
}).ToList();

Начиная с MVC 5.1, наиболее элегантным способом было бы использование метода EnumDropDownListFor помощника Html, если вам нужно заполнить select варианты на ваш взгляд:

@Html.EnumDropDownListFor(m => m.MyEnumProperty,new { @class="form-control"})

или GetSelectList метод EnumHelper в вашем контроллере:

var enumList = EnumHelper.GetSelectList(typeof (MyEnum));

Я сделал это с помощью статического метода, который я мог бы использовать повторно.

public static IEnumerable<SelectListItem> EnumToSelectList<T>()
{
    return (Enum.GetValues(typeof(T)).Cast<T>().Select(
        e => new SelectListItem() { Text = e.ToString(), Value = e.ToString() })).ToList();
}

Я использовал GetEnumSelectList из класса Html Helper

<select asp-for="MyProperty" class="form-control" asp-items="@Html.GetEnumSelectList<MyEnum>()" ></select>

Теперь я использовал Tuple<string, string> но вы можете преобразовать это, чтобы использовать что-нибудь:

var values = Enum.GetValues(typeof(DayOfWeek))
    .Cast<DayOfWeek>()
    .Select(d => Tuple.Create(((int)d).ToString(), d.ToString()))
    .ToList()

Ты можешь использовать Enum.GetNames() получить массив строк, содержащий имена элементов перечисления. Если ваши названия элементов удобны для пользователя, то это, вероятно, достаточно хорошо. В противном случае, вы можете создать свой собственный GetName() метод, который возвращает хорошее имя для каждого элемента.

ИЛИ - если перечисление никогда (или редко) не изменится, вы можете просто создать метод, который напрямую добавляет жестко закодированные элементы в ваш выпадающий список. Это, вероятно, более эффективно (если это важно для вас).

В Asp.Net Core просто используйте:

      <select asp-for="MyEnum" asp-items="Html.GetEnumSelectList(typeof(MyEnum))"></select>

Или же

Создать помощника

      public static class EnumHelper
{
    public static IEnumerable<SelectListItem> GetEnumSelectList<TEnum>(bool isNullable = false)
        where TEnum : struct
    {
        IList<SelectListItem> selectLists = Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(c => new SelectListItem()
        {
            Text = GetDisplayName(c),
            Value = c.ToString()
        }).ToList();

        if (isNullable)
        {
            selectLists.Add(new SelectListItem());
        }

        return selectLists.OrderBy(c => c.Value);
    }

    public static string GetDisplayName<TEnum>(TEnum enumVal)
    {
        DisplayAttribute attr = GetAttribute<DisplayAttribute>(enumVal);

        if (attr != null)
        {
            return attr.Name;
        }

        return enumVal?.ToString() ?? string.Empty;
    }

    public static TEnum GetAttribute<TEnum>(object enumVal) where TEnum : Attribute
    {
        if (enumVal == null)
        {
            return default;
        }

        Type type = enumVal.GetType();
        MemberInfo[] memInfo = type.GetMember(enumVal.ToString());

        if (memInfo.Length == 0)
        {
            return null;
        }

        object[] attributes = memInfo[0].GetCustomAttributes(typeof(TEnum), false);
        return attributes.Length > 0 ? (TEnum)attributes[0] : null;
    }
}

Использовать

      @using MyClass.Helpers;
    
<select asp-for="MyEnum" asp-items="EnumHelper.GetEnumSelectList<MyEnum>(true)">/select>

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

enum Color
{       
    Blue,
    [Category("Light")]
    [DisplayName("Light Blue")]
    LBlue,
    [Category("Dark")]
    [DisplayName("Dark Blue")]
    DBlue,
    Red,
    [Category("Dark")]
    [DisplayName("Dark Red")]
    DRed,
    [Category("Light")]
    [DisplayName("Light Red")]
    LRed,
    Green,
    [Category("Dark")]
    [DisplayName("Dark Green")]
    DGreen,
    [Category("Light")]
    [DisplayName("Light Green")]
    LGreen  
}

var list = typeof(Color).ToSelectList();

//or with custom options
var list = typeof(Color).ToSelectList(new SelectListOptions { Placeholder = "Please Select A Color"});

Вот ссылка на репозиторий github.

Другие вопросы по тегам