Как привязать список к ComboBox?

107

Я хочу подключить BindingSourceк списку объектов класса, а затем значение объектов к ComboBox.
Кто-нибудь может подсказать, как это сделать?

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

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

это мой класс, и я хочу привязать его nameполе к BindingSource, который затем может быть связан с ComboBox

Мобин
источник
Winforms то, что я хочу, - это помочь мне связать значения данных в поле имен объекта страны, остальное я
разберусь

Ответы:

160

Поскольку вы имеете в виду поле со списком, я предполагаю, что вы не хотите использовать двустороннюю привязку данных (если да, посмотрите на использование 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";

Для того, чтобы найти страну , выбранную в связанном поле со списком, вы могли бы сделать что - то вроде: Country country = (Country)comboBox1.SelectedItem;.

Если вы хотите, чтобы ComboBox обновлялся динамически, вам необходимо убедиться, что структура данных, которую вы установили в качестве DataSourceинструментов IBindingList; одна такая структура BindingList<T>.


Совет: убедитесь, что вы привязываете DisplayMemberк свойству класса, а не к общедоступному полю. Если ваш класс использует, public string Name { get; set; }он будет работать, но если он использует, public string Name;он не сможет получить доступ к значению и вместо этого будет отображать тип объекта для каждой строки в поле со списком.

Митч Уит
источник
... что может показаться очевидным, но тогда все очевидно в ретроспективе :)
demoncodemonkey
12
Вы можете пояснить или дополнить bindingSource1заявление?
beppe9000
1
System.Windows.Forms.BindingSource bindingSource1;
2.718
Является ли comboBox1.DataSource = bindingSource1.DataSource;правильно? или так должно быть comboBox1.DataSource = bindingSource1;?
Масуд
27

Для справки есть 2 способа использовать ComboBox / ListBox.

1) Добавьте объекты Country в свойство Items и выберите Country как Selecteditem. Чтобы использовать это, вы должны переопределить ToString of Country.

2) Используйте DataBinding, установите DataSource в IList (List <>) и используйте DisplayMember, ValueMember и SelectedValue

Для 2) вам сначала понадобится список стран

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

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

А затем в SelectionChanged,

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

}
Хенк Холтерман
источник
2
спасибо, но здесь небольшая проблема. Имена не отображаются в поле со списком при запуске приложения
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");
}

бум.

Роберт Тоннессен
источник
1
Это работает, за исключением того, что событие SelectionChanged не отображается в элементе управления в .NET 4.0. Я заменил это на SelectionChangeCommitted, и все в порядке.
Уэйд Хатлер
0

Попробуйте что-то вроде этого:

yourControl.DataSource = countryInstance.Cities;

И если вы используете WebForms, вам нужно будет добавить эту строку:

yourControl.DataBind();
Эндрю Хэйр
источник
1
а также comboBox1.DataBind (); функция я не вижу ее в решениях Я использую 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";

Это код, который я использую сейчас.

Мобин
источник
1
Несколько примечаний: bindingSource - это своего рода источник сквозных ссылок, вы на самом деле его сейчас не используете, возможно, хорошо. Но если вы хотите использовать его для связывания других вещей, используйте member_cbx = bindingSource1;
Хенк Холтерман,
-1

Если вы используете ToolStripComboBox, нет открытого источника данных (.NET 4.0):

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

toolStripComboBox1.Items.AddRange(someList.ToArray());
Джон М
источник
3
В этом случае вам нужно использовать ToolstripComboBox.ComboBox.DataSource. Похоже ToolstripComboBoxэто обертка для нормального ComboBox.
yu_ominae