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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:14:09  来源:igfitidea点击:

Bind List to DataSource

c#winformsdatasource

提问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> 优点/缺点:“当您将 Bi​​ndingSource 的数据源设置为 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 DisplayMemberproperty 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);