如何将一个列表绑定到下拉框?

119

我想将一个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,我需要的是帮助我连接国家对象名称字段中的数据值,其余部分我会自己解决。 - Mobin
7个回答

177

由于你提到了组合框,我猜想你不想使用双向数据绑定(如果需要的话,可以考虑使用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; 系统.窗体.数据绑定源 绑定源1; - 2.718
2
comboBox1.DataSource = bindingSource1.DataSource;正确吗?还是应该是comboBox1.DataSource = bindingSource1; - Masoud
这里的单向绑定是什么意思?它是否意味着当代码中使用 countries.Add("xxx")(列表)时,UI 将自动更新? - joe

28

背景介绍:使用ComboBox/ListBox有两种方法

1)将国家对象添加到Items属性中,并检索所选项作为Country。要使用此方法,您应该重写Country的ToString。

2)使用数据绑定,将DataSource设置为IList(List<>),并使用DisplayMember,ValueMember和SelectedValue。

对于第二种方法,您首先需要一个国家列表。

// 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

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");
}

嘭。


1
这段代码可以正常工作,但在.NET 4.0中似乎没有SelectionChanged事件。我将其替换为SelectionChangeCommitted,现在一切都很好。 - Wade Hatler

0
作为对此的小补充,我尝试将类似于这段代码的东西整合进去,但是添加/删除列表中的内容并没有在组合框中反映出来。这是因为添加/删除没有触发OnPropertyChange事件。
如果你想要添加/删除并且希望它们在组合框中反映出来,你需要将List<>更改为ObservableCollection。
List<Country> Countries

应该被替换为

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

OnPropertyChanged和ObservableCollection来自哪里?

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);
        }
    }

所有这些都在先前的解释这里中更为优美地表达了。


0
尝试像这样做:

yourControl.DataSource = countryInstance.Cities;

如果您正在使用WebForms,您需要添加以下行:

yourControl.DataBind();

1
我正在使用WinForms,包括comboBox1.DataBind()函数,但我在解决方案中找不到它。 - 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_CountryComboBox.ValueMember = "Name";

这是我现在正在使用的代码。


0
如果您正在使用ToolStripComboBox,那么没有公开的DataSource(.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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接