2011-04-12 15 views
36

Me gustaría vincular los valores de una enumeración con un control de cuadro combinado.Cómo vincular una enumeración al cuadro combinado

He escrito este código:

cboPriorLogicalOperator.DataSource = Enum.GetValues(typeof(MyEnum)) 
    .Cast<MyEnum>() 
    .Select(p => new { Key = (int)p, Value = p.ToString() }) 
    .ToList(); 

myComboBox.DisplayMember = "Value"; 
myComboBox.ValueMember = "Key"; 

funciona bien pero me pregunto si hay una manera más sencilla.

+0

¿Por qué está buscando una solución más simple si su solución funciona? –

+0

@ Ramhound: Pensé que tal vez hay una forma * directa *. Entiendo mi código, pero no todos pueden hacer eso simplemente. Así que busqué uno más simple. – Homam

+1

@Homam No sé si tu intención era esa, pero cuando diseñé el código para mi propia solución tuve que invertir la clave y los tipos de valores en mi declaración de selección para mostrar correctamente el valor en el cuadro combinado. Su método terminó mostrando las claves en el cuadro combinado. – gonzobrains

Respuesta

24

¡Creo que su código es hermoso!

La única mejora sería colocar el código en un Método de extensión.

EDIT:

Cuando pienso en ello, lo que se quiere hacer es usar la Enum como en la definición y no una instancia de la enumeración, que es requerido por los métodos de extensiones.

encontré este question, que lo resuelve muy bien:

public class SelectList 
{ 
    // Normal SelectList properties/methods go here 

    public static Of<T>() 
    { 
     Type t = typeof(T); 
     if (t.IsEnum) 
     { 
      var values = from Enum e in Enum.GetValues(type) 
         select new { ID = e, Name = e.ToString() }; 
      return new SelectList(values, "Id", "Name"); 
     } 
     return null; 
    } 
} 

// called with 
var list = SelectList.Of<Things>(); 

Sólo es posible que desee devolver un Dictionary<int, string> y no un SelectList, pero usted consigue la idea.

Edit2:

Aquí vamos con un ejemplo de código que cubre el caso que usted está mirando.

public class EnumList 
{ 
    public static IEnumerable<KeyValuePair<T, string>> Of<T>() 
    { 
     return Enum.GetValues(typeof (T)) 
      .Cast<T>() 
      .Select(p => new KeyValuePair<T, string>(p, p.ToString())) 
      .ToList(); 
    } 
} 

O quizá esta versión, donde la clave es una int

public class EnumList 
{ 
    public static IEnumerable<KeyValuePair<int, string>> Of<T>() 
    { 
     return Enum.GetValues(typeof (T)) 
      .Cast<T>() 
      .Select(p => new KeyValuePair<int, string>(Convert.ToInt32(p), p.ToString())) 
      .ToList(); 
    } 
} 
+0

Estoy de acuerdo. Hemos ampliado el cuadro combinado de winforms en nuestra propia versión y tenemos un método BindToEnum que funciona muy bien. Se parece mucho a este código también. – captncraig

+0

¿Qué devuelve 'Of'? – Homam

+0

Ah, lo echaron de menos en el ejemplo original. En su caso, devolvería 'Dictionary ', creo. –

6

Por qué no usar:

myComboBox.DataSource = Enum.GetValues(typeof(MyEnum)) 

?

+0

Porque esto no vincula pares de clave/valor. Para obtener un valor del cuadro combinado, debe enviar SelectedItem a la enumeración. Consulte http://msdn.microsoft.com/en-us/library/system.enum.getvalues.aspx, en la sección Observaciones. –

+0

Creo que si queremos establecer las condiciones en los datos recuperados, el código en cuestión es bastante bueno ... de lo contrario su código es mejor ... –

1
foreach (int r in Enum.GetValues(typeof(MyEnum))) 
{ 
    var item = new ListItem(Enum.GetName(typeof(MyEnum), r), r.ToString()); 
    ddl.Items.Add(item); 
} 
0

Recientemente me encontré con un problema en el que tenía una propiedad de enumeración anulable y necesitaba vincularlo a un ComboBox. Aquí está la solución que se me ocurrió:

using System; 
using System.Collections.Generic; 

namespace ActivitySchedule.Model 
{ 
    public class NullableEnum<T> where T : struct, IComparable 
    { 
     public string Display { get; private set; } 

     public T? Value { get; private set; } 

     public static implicit operator T?(NullableEnum<T> o) 
     { 
      return o.Value; 
     } 

     public static implicit operator NullableEnum<T>(T? o) 
     { 
      return new NullableEnum<T> 
      { 
       Display = o?.ToString() ?? "NA", 
       Value = o 
      }; 
     } 

     private NullableEnum() { } 

     public static IEnumerable<NullableEnum<T>> GetList() 
     { 
      var items = new List<NullableEnum<T>> 
      { 
       new NullableEnum<T> 
       { 
        Display = "NA", 
        Value = null 
       } 
      }; 

      var values = Enum.GetValues(typeof(T)); 

      foreach (T v in values) 
      { 
       items.Add(v); 
      } 

      return items; 
     } 
    } 
} 

que envuelve el objeto en una clase del controlador y cambiar el tipo de la propiedad de esta manera:

private MyClass myClass; 

public NullableEnum<MyEnum> MyEnum 
{ 
    get { return this.myClass.MyEnum; } 
    set { this.myClass.MyEnum = value.Value; } 
} 

(también podría ser una clase derivada y redefinir la propiedad)

Esto es como lo he usado:

var types = NullableEnum<MyEnum>.GetList(); 
this.comboBox1.DataSource = types; 
this.comboBox1.DisplayMember = "Display"; 
this.comboBox1.ValueMember = "Value"; 
this.comboBox1.Bindings.Add("SelectedValue", myClassController, "MyEnum"); 
-1
private void Form1_Load(object sender, EventArgs e) 
{ 
    comboBox1.DataSource = Enum.GetValues(typeof(Gender)); 
    Array gen = Enum.GetValues(typeof(Gender)); 
    List<KeyValuePair<string, char>> lstgender = new List<KeyValuePair<string,char>>(); 
    foreach(Gender g in gen) 
     lstgender.Add(new KeyValuePair<string,char>(g.ToString(),((char)g))); 
    comboBox1.DataSource = lstgender; 
    comboBox1.DisplayMember = "key"; 
    comboBox1.ValueMember = "value" 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    MessageBox.Show(comboBox1.SelectedValue.ToString()); 
} 

public class Student 
{ 
    public string stud_name { get; set; } 
    public Gender stud_gen { get; set; } 
} 

public enum Gender 
{ 
    Male='M', 
    Female='F' 
} 
+2

Por favor, agregue alguna explicación al código –

Cuestiones relacionadas