2013-02-28 11 views
7

リストをリストボックスのデータソースにバインドできるようにしたいのですが、リストが変更されるとリストボックスのUIが自動的に更新されます。 (ASPではなくWinforms)。ここ はサンプルです:DataSourceにバインドする

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

私はBindingList<Foo> fooList = new BindingList<Foo>();List<Foo> fooList = new List<Foo>();を交換する場合、それは動作します。しかし、私は愚か者の元のタイプを変更したくありません。 「あなたがリスト<へのBindingSourceのDataSourceを設定すると、それは内部的にあなたのリストをラップするするBindingListを作成します>」:listBox1.DataSource = new BindingList<Foo>(fooList);

EDIT:また、私はちょうどここList<T> vs BindingList<T> Advantages/DisAdvantagesイリヤJerebtsovから読んで私は仕事にこのような何かをしたいと思います。私のサンプルは、これが真実ではないことを実証していると思います。私のリスト<>はBindingList <に内部的にラップされていないようです。

+0

リスト<>は、オブザーバーがいつ更新するかを知るためのイベントを生成しません。オブザーバがUIコンポーネントであるか、ラッパーとして動作する別のリストであるかは関係ありません。バインド時にバインディングリストに変更することに異論があるのはなぜですか? – JRoughan

+0

ListをBindingListに変更したくないのは、既にプロジェクトのどこでもリストとして使用されているからです。私はすべてのメソッドのシグネチャを置き換える必要があります、私はすでに安定しているものを変更することを避けたいです。 – Michael

+0

戻り値の型をIList に変更した場合はどうなりますか?あなたはまだ変化の同じ量を持っていますか? – JRoughan

答えて

7

例ではBindingSourceはありません。 BindingSourceがINotifyPropertyChanged

では動作しません -

あなたは

が(コメントで指摘されたとして)があることに注意してくださいの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 

編集を使用するには、このようにそれを変更する必要があります

+0

これは動作します。残念ながら、fooListメンバのBarプロパティが他の場所で更新されると、ListBoxコンテンツは更新されません。同じ問題で悩まされている人がいます:http://social.msdn.microsoft。com/Forums/en-US/netfxbcl/thread/f54c125f-6f53-4446-9088-a193f6474059 – Larry

+0

@Laurent良い点。私はそれを知らなかった。編集された答え –

+0

素晴らしい、素晴らしい作品です。 – Michael

5

listBox1.DataSource = new BindingList<Foo>(fooList); 

試し、その後

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

これは、元のタイプを変更することなく、fooListを更新します。あなたはfooList[1].Bar = "Hello";

のようなバーのメンバーを変更した場合も、それはしかし、あなたがあるとして、「バー」、またはは.ToString()のオーバーライドを維持するために、リストボックスのDisplayMemberプロパティを設定する必要がありますリストボックスを更新しますFooクラスの定義では

たびにキャストする必要がないようにするためには、私はあなたのリストの定義と同じレベルにするBindingList変数を使用することをお勧め:

private List<Foo> fooList; 
private BindingList<Foo> fooListUI; 

fooListUI = new BindingList<Foo>(fooList); 
listBox1.DataSource = fooListUI; 

とボタンで:

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

あなたのソリューションに感謝しますが、私はJens Klosterのソリューションが少しエレガントであることを発見しました:) – Michael

+1

私はこれを尊重します! :-) – Larry

関連する問題