C# 将列表绑定到数据源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15141953/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bind List to DataSource
提问by KVM
I want to be able to bind a list to a listbox datasource and when the list is modified, the listbox's UI automatically updated. (Winforms not ASP). Here is a sample :
我希望能够将列表绑定到列表框数据源,并且在修改列表时,列表框的 UI 会自动更新。(Winforms 不是 ASP)。这是一个示例:
private List<Foo> fooList = new List<Foo>();
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_;
}
}
If I replace List<Foo> fooList = new List<Foo>();
by BindingList<Foo> fooList = new BindingList<Foo>();
then it works. But I don't want to change the original type of foolist. I would like something like this to work : listBox1.DataSource = new BindingList<Foo>(fooList);
如果我更换List<Foo> fooList = new List<Foo>();
的BindingList<Foo> fooList = new BindingList<Foo>();
,然后它工作。但我不想改变原来的傻瓜类型。我想要这样的工作:listBox1.DataSource = new BindingList<Foo>(fooList);
EDIT : Also I just read here List<T> vs BindingList<T> Advantages/DisAdvantagesfrom Ilia Jerebtsov : "When you set a BindingSource's DataSource to a List<>, it internally creates a BindingList to wrap your list". I think my sample just demonstrates that this is not true : my List<> doesn't seem to be internally wrapped into a BindingList<>.
编辑:此外,我刚刚在这里阅读了Ilia Jerebtsov 的List<T> vs BindingList<T> 优点/缺点:“当您将 BindingSource 的数据源设置为 List<> 时,它会在内部创建一个 BindingList 来包装您的列表”。我认为我的示例只是表明这不是真的:我的 List<> 似乎没有在内部包装到 BindingList<> 中。
采纳答案by Jens Kloster
You don't have a BindingSourcein you example.
你的例子中没有BindingSource。
you need to modify it like this to use a 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
Edit
编辑
Be aware that (as was pointed out in comments) - the bindingsource does not work with INotifyPropertyChanged
请注意(正如评论中指出的那样)- bindingsource 不适用于 INotifyPropertyChanged
回答by Larry
Try
尝试
listBox1.DataSource = new BindingList<Foo>(fooList);
then
然后
private void button1_Click(object sender, EventArgs e)
{
Foo foo2 = new Foo("bar2");
(listBox1.DataSource as BindingList<Foo>).Add(foo2);
}
This will update fooList without having to change its original type. Also, it will update the ListBox when you change the Bar member like fooList[1].Bar = "Hello";
这将更新 fooList 而不必更改其原始类型。此外,当您更改 Bar 成员时,它会更新 ListBox,例如fooList[1].Bar = "Hello";
However, you will have to set the DisplayMember
property of the ListBox to "Bar", orto keep the .ToString() override as is in the Foo class definition.
但是,您必须DisplayMember
将 ListBox的属性设置为“Bar”,或者保持 .ToString() 覆盖在 Foo 类定义中。
In order to avoid to have to cast every time, I suggest you to use a BindingList variable at the same level as your List definition :
为了避免每次都必须强制转换,我建议您使用与 List 定义处于同一级别的 BindingList 变量:
private List<Foo> fooList;
private BindingList<Foo> fooListUI;
fooListUI = new BindingList<Foo>(fooList);
listBox1.DataSource = fooListUI;
and in the button :
并在按钮中:
Foo foo2 = new Foo("bar2");
fooListUI.Add(foo2);