将列表绑定到DataSource

我希望能够将列表绑定到列表框数据源,并且在修改列表时,列表框的UI会自动更新。 (Winforms不是ASP)。 这是一个示例:

private List fooList = new List(); private void Form1_Load(object sender, EventArgs e) { //Add first Foo in fooList Foo foo1 = new Foo("bar1"); fooList.Add(foo1); //Bind fooList to the listBox listBox1.DataSource = fooList; //I can see bar1 in the listbox as expected } private void button1_Click(object sender, EventArgs e) { //Add anthoter Foo in fooList Foo foo2 = new Foo("bar2"); fooList.Add(foo2); //I expect the listBox UI to be updated thanks to INotifyPropertyChanged, but it's not } class Foo : INotifyPropertyChanged { private string bar_ ; public string Bar { get { return bar_; } set { bar_ = value; NotifyPropertyChanged("Bar"); } } public Foo(string bar) { this.Bar = bar; } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } public override string ToString() { return bar_; } } 

如果我替换List fooList = new List(); by BindingList fooList = new BindingList(); 然后它工作。 但我不想改变原来的傻瓜式。 我希望这样的工作: listBox1.DataSource = new BindingList(fooList);

编辑:我也在这里阅读List vs BindingList 来自Ilia Jerebtsov的优点/ DisAdvantages :“当你将BindingSource的DataSource设置为List 时,它会在内部创建一个BindingList来包装你的列表”。 我认为我的示例只是证明了这不是真的:我的List 似乎没有内部包装到BindingList 中。

您的示例中没有BindingSource 。

您需要像这样修改它以使用BindingSource

  var bs = new BindingSource(); Foo foo1 = new Foo("bar1"); fooList.Add(foo1); bs.DataSource = fooList; //<-- point of interrest //Bind fooList to the listBox listBox1.DataSource = bs; //<-- notes it takes the entire bindingSource 

编辑

请注意(正如评论中指出的那样) - bindingsource不能与INotifyPropertyChanged

尝试

 listBox1.DataSource = new BindingList(fooList); 

然后

 private void button1_Click(object sender, EventArgs e) { Foo foo2 = new Foo("bar2"); (listBox1.DataSource as BindingList).Add(foo2); } 

这将更新fooList而无需更改其原始类型。 此外,它会在您更改Bar成员时更新ListBox,如fooList[1].Bar = "Hello";

但是,您必须将ListBox的DisplayMember属性设置为“Bar”, 或者保持.ToString()覆盖在Foo类定义中。

为了避免每次都要进行强制转换,我建议你使用与List定义相同级别的BindingList变量:

 private List fooList; private BindingList fooListUI; fooListUI = new BindingList(fooList); listBox1.DataSource = fooListUI; 

并在按钮中:

 Foo foo2 = new Foo("bar2"); fooListUI.Add(foo2);