Как я могу преобразовать перечисление в список<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"});