2010-12-18 17 views
1

複雑なオブジェクトのリストと、BindingSourceを使用してこのリストにバインドされたListBoxがあります。ユーザーがリストボックス内の項目を選択すると、PropertyGridを使用してそのプロパティを編集し、TextBoxを介してテキストを個別に編集できます。プロパティはのBindingSourceのCurrentItemChangedが呼び出され、PropertyGridのを介して変更されますが、私は、ユーザーがちょうどここでのTextBoxオブジェクトプロパティは変更されますが、バインドされたListBoxは更新されません。

を編集するときにデータバインディングを更新して問題を抱えている場合は、より良い私の状況を説明するためのいくつかのコードです:


class Song 
{ 
    public string Title{get;set} 
    [Browsable(false)] 
    public string Text{get;set;} 
    ... 
} 

class SongBook 
{ 
    public List Songs {get;set;} 
    ... 
} 

// Initialization: we are setting ListBox's DataSource to songBookBindingSource 
private void InitializeComponent() 
{ 
    ... 
    this.allSongsList.DataSource = this.songBookBindingSource; 
    ... 
} 

// We create new SongBook object, and set BindingSource's DataSource to 
// list of songs in songbook 
private void OpenSongBook() 
{ 
    ... 
    currentSongBook.Deserialize(path); 
    songBookBindingSource.DataSource = currentSongBook.Songs; 
} 

// When user selects a song in ListBox, we try to edit it's properties 
private void allSongsList_SelectedValueChanged(object sender, EventArgs e) 
{ 
    ... 
    songProps.SelectedObject = allSongsList.SelectedItem; 
    songTextEdit.Text = (allSongsList.SelectedItem as Song).Text; 
} 

// This get called whenever user changes something in TextBox. 
// If it does, we want to mark song as Unsaved and refresh 
// ListBox, so it would display a nice little "*" next to it! 
private void songTextEdit_TextChanged(object sender, EventArgs e) 
{ 
    currentSong.Text = editSongTextBox.Text; 
    currentSong.Unsaved = true; 

    // As far as I understand, this SHOULD make ListBox bound to songBookBindingSource 
    // update its items. But it does not! How do I make it understand that data changed? 
    songBookBindingSource.RaiseListChangedEvents = true; 

    // And if I do this, ListBox DOES gets updated, but something also inserts A COPY OF CURRENT ITEM 
    // into it. If I select it, allSongsList.SelectedItem throws "Out of bounds" exception. As far 
    // as I understand, it gets added only to ListBox, but NOT to underlying List. But why is it 
    // even getting added at all?! 
    // songBookBindingSource.ResetCurrentItem(); 
} 

私はのように感じます.NET Frameworkは、私を嫌って:)

答えて

2

あなたのオブジェクトがINotifyPropertyChangedを実装する必要があるときに、プロパティが変更されると、そのように結合が更新されます:

class Song : INotifyPropertyChanged 
{ 
    private string _title; 
    public string Title 
    { 
     get { return _title; } 
     set 
     { 
      _title = value; 
      OnPropertyChanged("Title"); 
     } 
    } 

    private string _text; 
    [Browsable(false)] 
    public string Text 
    { 
     get { return _text; } 
     set 
     { 
      _text = value; 
      OnPropertyChanged("Text"); 
     } 
    } 
    ... 


    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
+0

ええと、私はすべての 'set'実装からOnPropertyChangedを呼び出す必要がありますか?私のために自動構築されたgetters/setterはありませんか?また、私はまだ興味があります - PropertyGirdからプロパティを変更すると、リフレッシュが発生しますが、直接変更はしません。 PropertyGirdは、変更されたプロパティに新しい値を代入する以外の何かをしますか? – MaxEd

+0

はい、すべての設定者からOnPropertyChangedを呼び出す必要があります(申し訳ありませんが、私の例では忘れてしまいました)ので、自動プロパティは使用できません。なぜそれがPropertyGridで動作するのかわかりません。 –

+0

OK、ありがとうございます。フレームワークは神秘的な方法で動作します:) – MaxEd

関連する問題