2009-07-10 48 views
55

Imagínese que tengo una enumeración como este (sólo como ejemplo):Cómo obtener los valores de una enumeración en un SelectList

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

¿Cómo puedo escribir una rutina para obtener estos valores en un sistema. Web.Mvc.SelectList, dado que los contenidos de la enumeración están sujetos a cambios en el futuro? Quiero conseguir cada nombre enumeraciones como el texto de la opción, y su valor como texto de valor, como este:

<select> 
    <option value="0">Horizontal</option> 
    <option value="1">Vertical</option> 
    <option value="2">Diagonal</option> 
</select> 

Esto es lo mejor que puedo llegar a hasta el momento:

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

Sin embargo esto siempre representa el texto de la opción como 'System.Web.Mvc.ListItem'. La depuración a través de esto también me muestra que Enum.GetValues ​​() está devolviendo 'Horizontal, Vertical', etc. en lugar de 0, 1 como hubiera esperado, lo que me hace preguntar cuál es la diferencia entre Enum.GetName() y Enum. GetValue()

+1

Este es un gran duplicado de http://stackoverflow.com/questions/1102022/display-enum-in-combobox-with-spaces y muchos, muchos otros. –

+0

[Los detalles de las enumeraciones de C#] (http://www.codeducky.org/ins-outs-c-enums/) describe la conversión entre cadenas, números y enumeraciones, así como la forma de enumerar los valores de una enumeración. – ChaseMedallion

Respuesta

22

Para obtener el valor de una enumeración, es necesario especificar la enumeración de su tipo subyacente:

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

¡Gracias! Pensé en esto, pero pensé que podría haber una manera de hacerlo sin lanzar. –

73

Ha sido un tiempo desde que he tenido que hacer esto, pero creo que esto debería funcionar.

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

¡Casi funciona, solo necesita un cambio menor! Su código establecerá el valor del Texto cuando el OP lo desee como un número entero. Sin embargo, una solución fácil. Cambiar 'ID = d' a' ID = (int) d'. ¡Gracias por publicar esto, nunca lo hubiera pensado! – Chris

+0

Excelente respuesta, aunque encontré que para rellenar previamente el menú desplegable, el valor tenía que ser la representación de texto de la enumeración, no del número entero. –

3
quizás no

una respuesta exacta a la pregunta, pero en escenarios CRUD i normalmente implementa algo como esto:

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 se llama antes de Vista ("Crear") y View ("Editar"), a continuación, y en la vista:

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

y eso es todo ..

29

Esto es lo acabo de hacer y personalmente creo que es atractiva:

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

Voy a hacer algunas cosas traducción, finalmente, por lo que el valor = enu.ToString() va a hacer una llamada a algo en alguna parte.

+1

Tengo un problema con este código. El "valor" de la lista de selección es el mismo que el "texto". Al usar Enums con EntityFramework, el valor guardado de nuevo en la base de datos debe ser un int. – meffect

+0

Bien, bien, haga esto luego: Value = (int) enu – Dann

+2

(int) enu no funciona –

4

O:

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

que quería hacer algo muy similar a la solución de Dann, pero necesitaba que el valor sea un int y el texto a ser la representación de cadena de la enumeración. Esto es lo que ocurrió:

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

Esta es, de lejos, la mejor respuesta. Valor necesario para ser una representación int de enum. –

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

tengo más clases y métodos, por diversas razones:

Enum a la colección de artículos

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

Creación selectlist en el controlador de

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

En ASP.NET MVC Core esto se hace con tag helpers.

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

Qué buena manera en .NET Core –

0

tuve muchos Selectlists de enumeración y, después de mucha caza y tamizado, se encontró que la toma de una ayuda genérica funcionó mejor para mí. Devuelve el índice o descriptor como el valor SelectList, y la descripción como el texto SelectList:

Enum:

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

Ayudante:

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

Uso: Establezca el parámetro en 'true' para los índices como valor:

var descriptorsAsValue = Selectlists.EnumSelectlist<Your_Enum>(); 
var indicesAsValue = Selectlists.EnumSelectlist<Your_Enum>(true); 
Cuestiones relacionadas