2009-07-10 2 views
55

Представьте меня есть перечисление таких, как это (только в качестве примера):Как получить значение перечисления в SelectList

public enum Direction{ 
    Horizontal = 0, 
    Vertical = 1, 
    Diagonal = 2 
} 

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

Однако это всегда отображает текст опции как «System.Web.Mvc.ListItem». Отладка через это также показывает мне, что Enum.GetValues ​​() возвращает «Горизонтальный, вертикальный» и т. Д. Вместо 0, 1, как я и ожидал, что заставляет меня задаться вопросом, какая разница между Enum.GetName() и Enum. GetValue().

+1

Это большой дубликат http://stackoverflow.com/questions/1102022/display-enum-in-combobox-with-spaces и многих других. –

+0

[Вложения и ограничения перечислений C#] (http://www.codeducky.org/ins-outs-c-enums/) описывает преобразование строк, чисел и перечислений, а также перечисление значений перечисления. – ChaseMedallion

ответ

22

Чтобы получить значение перечисления вам нужно бросить перечисление его базового типа:

Value = ((int)i).ToString(); 
+0

Спасибо! Я подумал об этом, но думал, что это может быть способ сделать это без кастинга. –

73

Это было некоторое время, так как я должен был сделать это, но я думаю, что это должно работать.

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); 
+5

Практически все работает, требуется только небольшое изменение! Ваш код установит значение в текст, когда OP хочет, чтобы оно было целым числом. Легко исправить, хотя. Измените 'ID = d' на' ID = (int) d'. Спасибо, что опубликовали это, я никогда бы не подумал об этом! – Chris

+0

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

3

возможно не точный ответ на этот вопрос, но в сценариях 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 ("Создать") и View ("Edit"), а затем и в представлении:

<%= Html.DropDownList("Fetcher") %> 

и это все ..

29

Это что я только что сделал, и лично я думаю, что его сексуальная:

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

Я собираюсь сделать некоторые вещи, в конце концов перевода так Value = enu.ToString() будет делать вызов, чтобы что-то где-то.

+1

У меня проблема с этим кодом. «Значение» в SelectList такое же, как «Текст». При использовании Enums с EntityFramework значение, сохраненное в базе данных, должно быть int. – meffect

+0

Хорошо, тогда сделайте следующее: Value = (int) enu – Dann

+2

(int) enu не работает –

4

Или:

foreach (string item in Enum.GetNames(typeof(MyEnum))) 
{ 
    myDropDownList.Items.Add(new ListItem(item, ((int)((MyEnum)Enum.Parse(typeof(MyEnum), item))).ToString())); 
} 
16

Я хотел сделать что-то очень похожее на решение Данна, но мне нужно значение, которое должно быть в Int и текст, чтобы быть строка представление Enum. Это то, что я придумал:

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(); 
    } 
+0

Это, безусловно, лучший ответ. Значение, которое должно быть int-представлением перечисления. –

3
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); 
     } 
    } 
4
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())) 
      }); 
0

У меня есть несколько классов и методов по различным причинам:

Enum в коллекции элементов

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(); 
    } 
} 

Создание SelectList в контроллере

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" }) 
3

В ASP.NET MVC ядра это делается с tag helpers.

<select asp-items="Html.GetEnumSelectList<Direction>()"></select> 
+0

Какой хороший способ в .NET Core –

0

У меня было много перечислений Selectlists и, после долгих охоты и просеивания, обнаружил, что делает общий помощник работал лучше для меня. Она возвращает индекс или дескриптор в качестве значения SelectList, и описание как текст SelectList:

Enum:

public enum Your_Enum 
{ 
    [Description("Description 1")] 
    item_one, 
    [Description("Description 2")] 
    item_two 
} 

Helper:

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);