简体   繁体   English

将列表绑定到DataSource

[英]Bind List to DataSource

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. 我希望能够将列表绑定到列表框数据源,并且当列表被修改时,列表框的UI会自动更新。 (Winforms not ASP). (Winforms不是ASP)。 Here is a sample : 这是一个示例:

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>(); 如果我替换List<Foo> fooList = new List<Foo>(); by BindingList<Foo> fooList = new BindingList<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); 我希望这样的工作: listBox1.DataSource = new BindingList<Foo>(fooList);

EDIT : Also I just read here List<T> vs BindingList<T> Advantages/DisAdvantages from Ilia Jerebtsov : "When you set a BindingSource's DataSource to a List<>, it internally creates a BindingList to wrap your list". 编辑:我也读到这里List <T> vs BindingList <T>来自Ilia Jerebtsov的优点/ DisAdvantages :“当你将BindingSource的DataSource设置为List <>时,它会在内部创建一个BindingList来包装你的列表”。 I think my sample just demonstrates that this is not true : my List<> doesn't seem to be internally wrapped into a BindingList<>. 我认为我的示例只是证明了这不是真的:我的List <>似乎没有内部包装到BindingList <>中。

You don't have a BindingSource in 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

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. 这将更新fooList而无需更改其原始类型。 Also, it will update the ListBox when you change the Bar member like fooList[1].Bar = "Hello"; 此外,它会在您更改Bar成员时更新ListBox,如fooList[1].Bar = "Hello";

However, you will have to set the DisplayMember property of the ListBox to "Bar", or to keep the .ToString() override as is in the Foo class definition. 但是,您必须将ListBox的DisplayMember属性设置为“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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM