Reputation: 362
I have a List of complex objects, and a ListBox that is bound to this List with BindingSource. When user selects items in listbox, he can edit it's properties via PropertyGrid and it's text separately via TextBox. When property is changed via PropertyGrid, BindingSource's CurrentItemChanged is called, but I'm having problems with updating DataBinding when users just edits TextBox
Here is some code to explain my situation better:
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();
}
I feel like .NET Framework hates me :)
Upvotes: 1
Views: 1668
Reputation: 292405
Your objects need to implement INotifyPropertyChanged
, that way the binding will refresh when a property changes:
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));
}
}
Upvotes: 2