¿Cómo vincular una lista a un ComboBox?

107

Quiero conectar un BindingSourcea una lista de objetos de clase y luego el valor de los objetos a un ComboBox.
¿Alguien puede sugerir cómo hacerlo?

public class Country
{
    public string Name { get; set; }
    public IList<City> Cities { get; set; }

    public Country()
    {
        Cities = new List<City>();
    }
}

es mi clase y quiero vincular su namecampo a un BindingSource que luego podría asociarse con un ComboBox

Mobin
fuente
Winforms lo que quiero es ayudarme a conectar los valores de datos en el campo de nombres del objeto de país, resto, lo resolveré
Mobin

Respuestas:

160

Como se refiere a un cuadro combinado, supongo que no desea utilizar el enlace de datos bidireccional (si es así, utilice un BindingList)

public class Country
{
    public string Name { get; set; }
    public IList<City> Cities { get; set; }
    public Country(string _name)
    {
        Cities = new List<City>();
        Name = _name;
    }
}



List<Country> countries = new List<Country> { new Country("UK"), 
                                     new Country("Australia"), 
                                     new Country("France") };

var bindingSource1 = new BindingSource();
bindingSource1.DataSource = countries;

comboBox1.DataSource = bindingSource1.DataSource;

comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "Name";

Para encontrar el país seleccionado en el cuadro combinado encuadernado, deberías hacer algo como: Country country = (Country)comboBox1.SelectedItem;.

Si desea que el ComboBox se actualice dinámicamente, deberá asegurarse de que la estructura de datos que ha establecido como DataSourceimplementos IBindingList; una de esas estructuras es BindingList<T>.


Consejo: asegúrese de vincular el DisplayMembera una propiedad de la clase y no a un campo público. Si su clase lo usa public string Name { get; set; }, funcionará, pero si lo usa public string Name;, no podrá acceder al valor y, en su lugar, mostrará el tipo de objeto para cada línea en el cuadro combinado.

Trigo Mitch
fuente
... lo que puede parecer obvio, pero luego todo es obvio en retrospectiva :)
demoncodemonkey
12
¿Puede explicar o agregar bindingSource1la declaración?
beppe9000
1
System.Windows.Forms.BindingSource bindingSource1;
2.718
Es comboBox1.DataSource = bindingSource1.DataSource;correcto? o debería ser comboBox1.DataSource = bindingSource1;?
Masoud
27

Para un fondo, hay 2 formas de usar un ComboBox / ListBox

1) Agregue objetos de país a la propiedad Elementos y recupere un país como elemento seleccionado. Para usar esto, debe anular la ToString of Country.

2) Use DataBinding, establezca DataSource en un IList (List <>) y use DisplayMember, ValueMember y SelectedValue

Para 2) primero necesitará una lista de países

// not tested, schematic:
List<Country> countries = ...;
...; // fill 

comboBox1.DataSource = countries;
comboBox1.DisplayMember="Name";
comboBox1.ValueMember="Cities";

Y luego, en SelectionChanged,

if (comboBox1.Selecteditem != null)
{
   comboBox2.DataSource=comboBox1.SelectedValue;

}
Henk Holterman
fuente
2
gracias, pero hay un pequeño problema aquí, los nombres no son visibles en el cuadro combinado cuando se ejecuta la aplicación
Mobin
23
public MainWindow(){
    List<person> personList = new List<person>();

    personList.Add(new person { name = "rob", age = 32 } );
    personList.Add(new person { name = "annie", age = 24 } );
    personList.Add(new person { name = "paul", age = 19 } );

    comboBox1.DataSource = personList;
    comboBox1.DisplayMember = "name";

    comboBox1.SelectionChanged += new SelectionChangedEventHandler(comboBox1_SelectionChanged);
}


void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    person selectedPerson = comboBox1.SelectedItem as person;
    messageBox.Show(selectedPerson.name, "caption goes here");
}

auge.

Robert Tonnessen
fuente
1
Esto funciona excepto que el evento SelectionChanged no parece estar en el control en .NET 4.0. Reemplacé eso con SelectionChangeCommitted y todo está bien.
Wade Hatler
0

Intente algo como esto:

yourControl.DataSource = countryInstance.Cities;

Y si está utilizando WebForms, deberá agregar esta línea:

yourControl.DataBind();
Andrew Hare
fuente
1
así como comboBox1.DataBind (); función no lo veo en soluciones Estoy usando winforms
Mobin
0
public class Country
{
    public string Name { get; set; }
    public IList<City> Cities { get; set; }

    public Country()
    {
        Cities = new List<City>();
    }
}

public class City 
{
    public string Name { get; set; } 
}

List<Country> Countries = new List<Country>
{
    new Country
    {
        Name = "Germany",
        Cities =
        {
            new City {Name = "Berlin"},
            new City {Name = "Hamburg"}
        }
    },
    new Country
    {
        Name = "England",
        Cities =
        {
            new City {Name = "London"},
            new City {Name = "Birmingham"}
        }
    }
};
bindingSource1.DataSource = Countries;
member_CountryComboBox.DataSource = bindingSource1.DataSource;
member_CountryComboBox.DisplayMember = "Name";
member_CountryCombo

Box.ValueMember = "Name";

Este es el código que estoy usando ahora.

Mobin
fuente
1
Algunas notas: Un bindingSource es una especie de fuente de enlace, realmente no la estás usando ahora, probablemente Ok. Pero si desea usarlo para vincular otras cosas, use member_cbx = bindingSource1;
Henk Holterman
-1

Si está utilizando un ToolStripComboBox, no hay ningún DataSource expuesto (.NET 4.0):

List<string> someList = new List<string>();
someList.Add("value");
someList.Add("value");
someList.Add("value");

toolStripComboBox1.Items.AddRange(someList.ToArray());
John M
fuente
3
En ese caso, debe usar ToolstripComboBox.ComboBox.DataSource. Parece que ToolstripComboBoxes un envoltorio para un normal ComboBox.
yu_ominae