Como vincular uma lista a uma ComboBox?

107

Eu quero conectar um BindingSourcea uma lista de objetos de classe e, em seguida, o valor dos objetos a um ComboBox.
Alguém pode sugerir como fazer isso?

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

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

é minha classe e quero vincular seu namecampo a um BindingSource que pode ser associado a um ComboBox

Mobin
fonte
Winforms, o que eu quero é me ajudar a conectar os valores dos dados no campo de nomes do objeto do país, vou descobrir
Mobin

Respostas:

160

Como você está se referindo a uma caixa de combinação, estou assumindo que você não deseja usar a ligação de dados bidirecional (em caso afirmativo, observe o uso de um 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 o país selecionado no combobox ligado, você faria algo como: Country country = (Country)comboBox1.SelectedItem;.

Se você deseja que o ComboBox seja atualizado dinamicamente, você precisará certificar-se de que a estrutura de dados que você configurou como o DataSourceimplementa IBindingList; uma dessas estruturas é BindingList<T>.


Dica: certifique-se de que você está associando o DisplayMembera uma propriedade na classe e não a um campo público. Se sua classe usa public string Name { get; set; }, vai funcionar, mas se usar public string Name;, não será capaz de acessar o valor e, em vez disso, exibirá o tipo de objeto para cada linha na caixa de combinação.

Trigo mitch
fonte
... o que pode parecer óbvio, mas tudo é óbvio em retrospectiva :)
demoncodemonkey
12
Você pode explicar ou adicionar bindingSource1a declaração de?
beppe9000
1
System.Windows.Forms.BindingSource bindingSource1;
2.718
Está comboBox1.DataSource = bindingSource1.DataSource;correto? ou deveria ser comboBox1.DataSource = bindingSource1;?
Masoud de
27

Para um backgrounder, existem 2 maneiras de usar uma ComboBox / ListBox

1) Adicione objetos de país à propriedade de itens e recupere um país como item selecionado. Para usar isso, você deve substituir o ToString de País.

2) Use DataBinding, defina DataSource como IList (List <>) e use DisplayMember, ValueMember e SelectedValue

Para 2) você precisará primeiro de uma lista de países

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

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

E então no SelectionChanged,

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

}
Henk Holterman
fonte
2
obrigado, mas um
pequeno
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");
}

estrondo.

Robert Tonnessen
fonte
1
Isso funciona, exceto que o evento SelectionChanged não parece estar no controle no .NET 4.0. Substituí isso por SelectionChangeCommitted e está tudo bem.
Wade Hatler
0

Experimente algo assim:

yourControl.DataSource = countryInstance.Cities;

E se você estiver usando WebForms, você precisará adicionar esta linha:

yourControl.DataBind();
Andrew Hare
fonte
1
bem como comboBox1.DataBind (); função não vejo isso nas soluções que estou 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 é o código que estou usando agora.

Mobin
fonte
1
Algumas notas: Um bindingSource é um tipo de fonte link-through, você não a está usando agora, provavelmente ok. Mas se você quiser usá-lo para vincular outras coisas, use member_cbx = bindingSource1;
Henk Holterman,
-1

Se você estiver usando um ToolStripComboBox, não há DataSource exposta (.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
fonte
3
Nesse caso, você precisa usar ToolstripComboBox.ComboBox.DataSource. Parece ToolstripComboBoxum invólucro para um normal ComboBox.
yu_ominae