I have a DataGridView bound to a bindingsource which is bound to a List
. The user clicks a row that goes to a form with textboxes, etc. The textboxes a
I set up a fairly simple mechanism, as follows:
I can share the source if anyone is interested.
If your object within the List support the INotifyPropertyChanged event and you replace the List<T>
by a BindingList<T> you can subscribe to the ListChanged event of the BindingList to get informed about any changes made by the user.
After trying different thing I ended up with this piece of code:
private MyClass currentItem = null;
private bool itemDirty = false; // can be used for "do you want to save?"
private void bindingSource_CurrentChanged(object sender, EventArgs e)
{
var handler = new PropertyChangedEventHandler((s, e2) => itemDirty = true);
var crnt = currentItem as INotifyPropertyChanged;
if(crnt != null) crnt.PropertyChanged -= handler;
currentItem = (MyClass)bindingSource.Current;
crnt = currentItem as INotifyPropertyChanged;
if(crnt != null) crnt.PropertyChanged += handler;
itemDirty = false;
}
It works fine for me, although I save lots of state information in the Windows Form's instance fields. However, twiddling with CurrentChanged
and CurrentItemChanged
did not help me.
If you're bound to a DataSet then you're in luck: it has a HasChanges Property. You can get the actual changes by calling GetChanges on the dataset. This returns a new dataset containing a copy of all changed rows
A simpler approach would be to subscribe to the BindingSource's ListChanged event and set an IsDirty flag based on the event type.
categoryBindingSource.ListChanged +=
new System.ComponentModel.ListChangedEventHandler(categoryBindingSource_ListChanged);
and set IsDirty = true in the event method...
void customerAccountBindingSource_ListChanged(object sender, system.ComponentModel.ListChangedEventArgs e)
{
if (e.ListChangedType == System.ComponentModel.ListChangedType.ItemChanged)
_isDirty = true;
}
A word of caution here, it would not be able to detect when the modified value is still same as the original value. Memberwise.Clone
can be used additionally if that level of accuracy is required.
From my updated question I found I had to store a current version of the object at BeginEdit using Memberwise.Clone and then in CancelEdit I restored that to the current.