2010-12-18 72 views
1

我有一個複雜對象的列表,以及一個綁定到此列表與BindingSource的列表框。當用戶選擇列表框中的項目時,他可以通過PropertyGrid編輯它的屬性,並通過TextBox單獨編輯它的文本。當屬性通過PropertyGrid的改變,BindingSource的的CurrentItemChanged叫,但我有與更新數據綁定時,用戶只需編輯文本框對象屬性發生變化,但綁定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框架恨我:)

回答

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/setters對我來說?此外,我仍然好奇 - 爲什麼從PropertyGird更改屬性會導致刷新,但直接更改不會? PropertyGird是否做了別的事情,而不僅僅是將新的值賦給改變後的屬性? – MaxEd 2010-12-18 22:33:34

+0

是的,你需要從所有setters調用OnPropertyChanged(對不起,在我的例子中忘了它),所以你不能使用自動屬性。不知道爲什麼它與PropertyGrid ... – 2010-12-18 22:45:55

+0

好吧,謝謝它必須做的。框架以神祕的方式工作:) – MaxEd 2010-12-19 07:32:49

相關問題