Jak powiązać listę z ComboBox?

107

Chcę połączyć a BindingSourcez listą obiektów klas, a następnie wartości obiektów do ComboBox.
Czy ktoś może podpowiedzieć, jak to zrobić?

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

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

jest moją klasą i chcę powiązać jej namepole z BindingSource, które można następnie skojarzyć z ComboBox

Mobin
źródło
Winforms co chcę to pomaga mi połączyć wartości danych w polu nazwy obiektu kraju odpocząć i będzie zrozumieć to
Mobin

Odpowiedzi:

160

Odnosząc się do combobox, zakładam, że nie chcesz używać dwukierunkowego wiązania danych (jeśli tak, spójrz na użycie 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";

Aby znaleźć wybranego kraju w oprawionego combobox, byś zrobił coś takiego: Country country = (Country)comboBox1.SelectedItem;.

Jeśli chcesz, aby ComboBox aktualizował się dynamicznie, musisz upewnić się, że struktura danych, którą ustawiłeś jako DataSourcenarzędzia IBindingList; jedna taka struktura jest BindingList<T>.


Wskazówka: upewnij się, że wiążesz DisplayMemberwłaściwość z właściwością klasy, a nie polem publicznym. Jeśli klasa używa public string Name { get; set; }, będzie działać, ale jeśli używa public string Name;, nie będzie w stanie uzyskać dostępu do wartości i zamiast tego wyświetli typ obiektu dla każdej linii w polu kombi.

Mitch Wheat
źródło
... co może wydawać się oczywiste, ale z perspektywy czasu wszystko jest oczywiste :)
demoncodemonkey
12
Czy możesz wyjaśnić lub dodać bindingSource1oświadczenie?
beppe9000
1
System.Windows.Forms.BindingSource bindingSource1;
2.718
Jest comboBox1.DataSource = bindingSource1.DataSource;poprawne? czy powinno być comboBox1.DataSource = bindingSource1;?
Masoud
27

W przypadku tła istnieją 2 sposoby korzystania z ComboBox / ListBox

1) Dodaj Country Objects do właściwości Items i pobierz kraj jako Selecteditem. Aby z tego skorzystać, należy zastąpić ToString of Country.

2) Użyj DataBinding, ustaw DataSource na IList (List <>) i użyj DisplayMember, ValueMember i SelectedValue

W przypadku 2) będziesz potrzebować najpierw listy krajów

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

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

Następnie w SelectionChanged,

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

}
Henk Holterman
źródło
2
dzięki, ale tu jest
mały
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");
}

Bum.

Robert Tonnessen
źródło
1
Działa to z wyjątkiem zdarzenia SelectionChanged nie wydaje się znajdować w kontrolce w .NET 4.0. Zastąpiłem to SelectionChangeCommitted i wszystko jest w porządku.
Wade Hatler
0

Spróbuj czegoś takiego:

yourControl.DataSource = countryInstance.Cities;

Jeśli korzystasz z formularzy internetowych, musisz dodać ten wiersz:

yourControl.DataBind();
Andrew Hare
źródło
1
a także comboBox1.DataBind (); funkcja nie widzę tego w rozwiązaniach używam 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";

To jest kod, którego teraz używam.

Mobin
źródło
1
Kilka uwag: bindingSource jest rodzajem źródła łączącego, tak naprawdę go teraz nie używasz, prawdopodobnie OK. Ale jeśli chcesz użyć go do łączenia innych rzeczy, użyj member_cbx = bindingSource1;
Henk Holterman
-1

Jeśli używasz ToolStripComboBox, nie ma udostępnionego źródła danych (.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.
źródło
3
W takim przypadku musisz użyć ToolstripComboBox.ComboBox.DataSource. Wygląda na to, że ToolstripComboBoxjest to opakowanie normalnego ComboBox.
yu_ominae,