Как получить значения перечисления в список выбора
представьте, что у меня есть перечисление, такое как это (просто в качестве примера):
public enum Direction{
Horizontal = 0,
Vertical = 1,
Diagonal = 2
}
как я могу написать процедуру, чтобы получить эти значения в систему.Сеть.Mvc.SelectList, учитывая, что содержание перечисления могут быть изменены в будущем? Я хочу получить имя каждого перечисления в качестве текста опции и его значение в качестве текста значения, например:
<select>
<option value="0">Horizontal</option>
<option value="1">Vertical</option>
<option value="2">Diagonal</option>
</select>
Это лучшее, что я могу придумать до сих пор:
public static SelectList GetDirectionSelectList()
{
Array values = Enum.GetValues(typeof(Direction));
List<ListItem> items = new List<ListItem>(values.Length);
foreach (var i in values)
{
items.Add(new ListItem
{
Text = Enum.GetName(typeof(Direction), i),
Value = i.ToString()
});
}
return new SelectList(items);
}
однако это всегда отображает опцию текст как ' система.Сеть.Mvc.Listitem элемент'. Отладка через это также показывает мне, что перечисление.GetValues() возвращает 'горизонтальные, вертикальные и т. д. вместо 0, 1, Как я ожидал, что заставляет меня задаться вопросом, в чем разница между перечислением.GetName () и перечисление.метод GetValue.)(
12 ответов:
чтобы получить значение перечисления, вам нужно привести перечисление к его базовому типу:
Value = ((int)i).ToString();
Это было некоторое время, так как я должен был сделать это, но я думаю, что это должно работать.
var directions = from Direction d in Enum.GetValues(typeof(Direction)) select new { ID = (int)d, Name = d.ToString() }; return new SelectList(directions , "ID", "Name", someSelectedValue);
появилась новая функция ASP.NET MVC 5.1 для этого.
http://www.asp.net/mvc/overview/releases/mvc51-release-notes#Enum
@Html.EnumDropDownListFor(model => model.Direction)
Это то, что я только что сделал, и лично я думаю, что это сексуально:
public static IEnumerable<SelectListItem> GetEnumSelectList<T>() { return (Enum.GetValues(typeof(T)).Cast<T>().Select( enu => new SelectListItem() { Text = enu.ToString(), Value = enu.ToString() })).ToList(); }
Я собираюсь сделать некоторые вещи перевода в конце концов, так что значение = enu.ToString () будет делать вызов к чему-то где-то.
Я хотел сделать что-то очень похожее на решение Данна, но мне нужно было, чтобы значение было int, а текст был строковым представлением перечисления. Вот что я придумал:
public static IEnumerable<SelectListItem> GetEnumSelectList<T>() { return (Enum.GetValues(typeof(T)).Cast<int>().Select(e => new SelectListItem() { Text = Enum.GetName(typeof(T), e), Value = e.ToString() })).ToList(); }
или:
foreach (string item in Enum.GetNames(typeof(MyEnum))) { myDropDownList.Items.Add(new ListItem(item, ((int)((MyEnum)Enum.Parse(typeof(MyEnum), item))).ToString())); }
return Enum .GetNames(typeof(ReceptionNumberType)) .Where(i => (ReceptionNumberType)(Enum.Parse(typeof(ReceptionNumberType), i.ToString())) < ReceptionNumberType.MCI) .Select(i => new { description = i, value = (Enum.Parse(typeof(ReceptionNumberType), i.ToString())) });
в ASP.NET ядро в MVC это делается с помощью tag helpers.
<select asp-items="Html.GetEnumSelectList<Direction>()"></select>
может быть, не точный ответ на вопрос, но в сценариях CRUD я обычно реализую что-то вроде этого:
private void PopulateViewdata4Selectlists(ImportJob job) { ViewData["Fetcher"] = from ImportFetcher d in Enum.GetValues(typeof(ImportFetcher)) select new SelectListItem { Value = ((int)d).ToString(), Text = d.ToString(), Selected = job.Fetcher == d }; }
PopulateViewdata4Selectlists
вызывается перед View ("Create") и View ("Edit"), затем и в представлении:<%= Html.DropDownList("Fetcher") %>
и это все..
public static SelectList ToSelectList<TEnum>(this TEnum enumObj) where TEnum : struct { if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj"); var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() }; //var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = e.ToString() }; return new SelectList(values, "ID", "Name", enumObj); } public static SelectList ToSelectList<TEnum>(this TEnum enumObj, string selectedValue) where TEnum : struct { if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj"); var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() }; //var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = e.ToString() }; if (string.IsNullOrWhiteSpace(selectedValue)) { return new SelectList(values, "ID", "Name", enumObj); } else { return new SelectList(values, "ID", "Name", selectedValue); } }
у меня больше классов и методов по разным причинам:
перечисление в коллекцию предметов
public static class EnumHelper { public static List<ItemDto> EnumToCollection<T>() { return (Enum.GetValues(typeof(T)).Cast<int>().Select( e => new ItemViewModel { IntKey = e, Value = Enum.GetName(typeof(T), e) })).ToList(); } }
создание списка выбора в контроллере
int selectedValue = 1; // resolved from anywhere ViewBag.Currency = new SelectList(EnumHelper.EnumToCollection<Currency>(), "Key", "Value", selectedValue);
MyView.cshtml
@Html.DropDownListFor(x => x.Currency, null, htmlAttributes: new { @class = "form-control" })
у меня было много списков выбора перечислений, и после долгой охоты и просеивания я обнаружил, что создание общего помощника лучше всего подходит для меня. Он возвращает индекс или дескриптор как значение Selectlist, а описание как текст Selectlist:
перечисление:
public enum Your_Enum { [Description("Description 1")] item_one, [Description("Description 2")] item_two }
помощник:
public static class Selectlists { public static SelectList EnumSelectlist<TEnum>(bool indexed = false) where TEnum : struct { return new SelectList(Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(item => new SelectListItem { Text = GetEnumDescription(item as Enum), Value = indexed ? Convert.ToInt32(item).ToString() : item.ToString() }).ToList(), "Value", "Text"); } // NOTE: returns Descriptor if there is no Description private static string GetEnumDescription(Enum value) { FieldInfo fi = value.GetType().GetField(value.ToString()); DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes != null && attributes.Length > 0) return attributes[0].Description; else return value.ToString(); } }
использование: Установите параметр 'true' для индексов в качестве значения:
var descriptorsAsValue = Selectlists.EnumSelectlist<Your_Enum>(); var indicesAsValue = Selectlists.EnumSelectlist<Your_Enum>(true);