2011-08-03 8 views
7

que tienen una enumeración de esta manera:.NET enlace de datos un cuadro combinado a una enumeración de la cadena con atributos Descripción

public enum Cities 
{ 
    [Description("New York City")] 
    NewYork, 
    [Description("Los Angeles")] 
    LosAngeles, 
    Washington, 
    [Description("San Antonio")] 
    SanAntonio, 
    Chicago 
} 

quiero obligar a un cuadro combinado y he intentado esto:

comboBox.DataSource = Enum.GetNames(typeof(Cities)); 

Pero eso muestra los valores en el cuadro combinado en lugar de la descripción de la cadena. Por lo que me pasa a esto:

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

public static IList ToList(this Type type) 
{ 
    ArrayList list = new ArrayList(); 
    Array enumValues = Enum.GetValues(type); 

    foreach (Enum value in enumValues) 
    { 
     list.Add(new KeyValuePair<Enum, string>(value, GetEnumDescription(value))); 
    } 

    return list; 
} 

Ahora el list.Add() resultados de llamadas en el valor y su descripción cadena que se está representada en el cuadro combinado, así que sustituyen

list.Add(new KeyValuePair<Enum, string>(value, GetEnumDescription(value))); 

con

list.Add(GetEnumDescription(value)); 

y ahora obtengo solo la cadena descriptiva que se muestra en el cuadro combinado, que es lo que quiero en última instancia. Ahora mi enlace de datos está roto porque no puede encontrar solo la descripción de la cadena en la enumeración. Pensé que esto podría estar relacionado con combobox.DisplayMember y combobox.ValueMember pero aún no he podido resolver el problema. ¿Alguien puede decirme cómo diablos puedo mostrar la cadena descriptiva pero hacer que mi enlace de datos use el valor para almacenar, etc.? ¡¡¡Gracias!!!

+0

Solo por curiosidad ... ¿por qué tienes que usar un Enum para esto? –

+0

Necesito mostrar varios cuadros combinados que contienen diferentes opciones fijas para que mis usuarios puedan elegir. Tal vez haya un cuadro combinado para mostrar cuatro colores (rojo, amarillo, verde, azul). Otro podría mostrar una lista de formas para que ellos elijan. Como estas son listas fijas, pensé que una enumeración tendría sentido.Tengo una clase de "datos" que modela todas estas cosas y cuando el usuario ha terminado de hacer sus selecciones en la interfaz de usuario, simplemente analizo las propiedades del objeto de datos y guardo los valores en un archivo. Eso responde tu pregunta? – user685869

+0

Sí, y funcionará bien de la forma en que lo hace, solo hace que el código sea un poco más complicado. Dado que esta es una lista codificada de todos modos, ¿cuál sería el inconveniente de crear una lista codificada en tiempo de ejecución como alternativa? –

Respuesta

9

Volvamos a su pregunta I answered hace unos días y la modificamos para adaptarla a sus nuevos requisitos. Así que guardaré el ejemplo colorEnum en lugar de su enumeración Cities en esta pregunta.

Está todo el camino hasta allí; tiene el código para pasar de la enumeración a la cadena de descripción; ahora solo necesitas regresar por el otro lado.

public static class EnumHelper 
{ 
    // your enum->string method (I just decluttered it a bit :)) 
    public static string GetEnumDescription(Enum value) 
    { 
     var fi = value.GetType().GetField(value.ToString()); 
     var attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 

     if (attributes.Length > 0) 
      return ((DescriptionAttribute)attributes[0]).Description; 
     else 
      return value.ToString();   
    } 

    // the method to go from string->enum 
    public static T GetEnumFromDescription<T>(string stringValue) 
     where T : struct 
    { 
     foreach (object e in Enum.GetValues(typeof(T)))   
      if (GetEnumDescription((Enum)e).Equals(stringValue)) 
       return (T)e; 
     throw new ArgumentException("No matching enum value found."); 
    } 

    // and a method to get a list of string values - no KeyValuePair needed 
    public static IEnumerable<string> GetEnumDescriptions(Type enumType) 
    { 
     var strings = new Collection<string>(); 
     foreach (Enum e in Enum.GetValues(enumType)) 
      strings.Add(GetEnumDescription(e)); 
     return strings; 
    } 
} 

Ahora, tome lo que tenías hace unos días ...

public class Person 
{ 
    [...] 
    public colorEnum FavoriteColor { get; set; } 
    public string FavoriteColorString 
    { 
     get { return FavoriteColor.ToString(); } 
     set { FavoriteColor = (colorEnum)Enum.Parse(typeof(colorEnum), value); } 
    } 
} 

y sólo cambiar a esto:

public class Person 
{ 
    [...] 
    public colorEnum FavoriteColor { get; set; } 
    public string FavoriteColorString 
    { 
     get { return EnumHelper.GetEnumDescription(FavoriteColor); } 
     set { FavoriteColor = EnumHelper.GetEnumFromDescription<colorEnum>(value); } 
    } 
} 

Al igual que antes, podrás enlazar el cuadro combinado SelectedItem valor a FavoriteColorString. No necesita establecer las propiedades DisplayMember o ValueMember si todavía está utilizando BindingSource como lo hizo en la otra pregunta, que supongo que es.

y cambiar el código poblar cuadro combinado de:

comboBoxFavoriteColor.DataSource = Enum.GetNames(typeof(colorEnum)); 

a

comboBoxFavoriteColor.DataSource = EnumHelper.GetEnumDescriptions(typeof(colorEnum)); 

Ahora usted tiene el mejor de los mundos. El usuario ve la descripción, su código contiene los nombres enum y el almacén de datos contiene los valores enum.

+0

Me has dado muchas respuestas excelentes durante la última semana y aprecio mucho la ayuda y las explicaciones. Como siempre, ¡gracias por compartir tu experiencia! – user685869

+1

@ user68: De nada. Por cierto, la razón por la que eliminé la verificación 'attributes! = Null' en' GetEnumDescription() 'es que' GetCustomAttributes() 'solo devuelve una matriz vacía cuando no encuentra ningún atributo. –

+0

@ user68: y una cosa más ... puedes apoyar mis respuestas y aceptarlas. Agradezco cualquier representante que pueda ganar. :) –

Cuestiones relacionadas