119

I want to connect a BindingSource to a list of class objects and then objects value to a ComboBox.
Can anyone suggest how to do it?

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

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

is my class and I want to bind its name field to a BindingSource which could be then associated with a ComboBox

Jimi
  • 29,621
  • 8
  • 43
  • 61
Mobin
  • 4,870
  • 15
  • 45
  • 51
  • Winforms what i want is help me connect the data values in names field of country object rest i will figure it out – Mobin Mar 02 '09 at 00:14

7 Answers7

177

As you are referring to a combobox, I'm assuming you don't want to use 2-way databinding (if so, look at using a 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";

To find the country selected in the bound combobox, you would do something like: Country country = (Country)comboBox1.SelectedItem;.

If you want the ComboBox to dynamically update you'll need to make sure that the data structure that you have set as the DataSource implements IBindingList; one such structure is BindingList<T>.


Tip: make sure that you are binding the DisplayMember to a Property on the class and not a public field. If you class uses public string Name { get; set; } it will work but if it uses public string Name; it will not be able to access the value and instead will display the object type for each line in the combo box.

LoukMouk
  • 503
  • 9
  • 29
Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
28

For a backgrounder, there are 2 ways to use a ComboBox/ListBox

1) Add Country Objects to the Items property and retrieve a Country as Selecteditem. To use this you should override the ToString of Country.

2) Use DataBinding, set the DataSource to a IList (List<>) and use DisplayMember, ValueMember and SelectedValue

For 2) you will need a list of countries first

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

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

And then in the SelectionChanged,

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

}
H H
  • 263,252
  • 30
  • 330
  • 514
  • 2
    thanks but a bit of a problem here the Names are not visible in the combobox when running the application – Mobin Mar 02 '09 at 00:31
24
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");
}

boom.

JYelton
  • 35,664
  • 27
  • 132
  • 191
  • 1
    This works except the SelectionChanged event doesn't appear to be on the control in .NET 4.0. I replaced that with SelectionChangeCommitted and all is well. – Wade Hatler Dec 31 '14 at 01:21
0

If you are using a ToolStripComboBox there is no DataSource exposed (.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
  • 14,338
  • 29
  • 91
  • 143
  • 3
    In that case you need to use `ToolstripComboBox.ComboBox.DataSource`. It looks like `ToolstripComboBox` is a wrapper for a normal `ComboBox`. – yu_ominae Feb 21 '13 at 06:11
0

Try something like this:

yourControl.DataSource = countryInstance.Cities;

And if you are using WebForms you will need to add this line:

yourControl.DataBind();
Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
  • 1
    as well as comboBox1.DataBind(); function i dont see it in solutions I am using winforms – Mobin Mar 02 '09 at 00:10
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_CountryComboBox.ValueMember = "Name";

This is the code I am using now.

dns_nx
  • 3,651
  • 4
  • 37
  • 66
Mobin
  • 4,870
  • 15
  • 45
  • 51
0

As a small addition to this, I tried to incorporate something similar to this code, and was frustrated that adding/removing from the list was not reflected in the ComboBox. This is because the Add/Remove does not trigger the OnPropertyChange.

If you want to Add/Remove and have them reflected in the ComboBox, you will need to change List<> to ObservableCollection

List<Country> Countries

Should be replaced with

    private ObservableCollection<Country> countries;
    public ObservableCollection<Country> Countries
    {
        get { return countries; }
        set
        {
            countries= value;
            OnPropertyChanged("Countries");
        }
    }

Where OnPropertyChanged and ObservableCollection comes from

using System.Runtime.CompilerServices;
using System.Collections.ObjectModel;
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }

All of this is more eloquently expressed in a previous explanation here