I have a BindingSource
that I'm using in winforms data binding and I'd like to have some sort of prompt for when the user attempts to close the form after they've made changes to the data. A sort of "Are you sure you want to exit without saving changes?"
I'm aware that I can do this via the BindingSource
's CurrencyManager.ItemChanged
event by just flipping a "has changed" boolean.
However, I want a more robust functionality. I'd like to know when the current data is different from the original data. The event just tells me if somethings changed. A user could still change a property, hit undo, and I would still think that there is a change in the data to save.
I want to mimic this similar functionality of notepad
If this is not possible, then should I go with the ItemChanged
event handler as outlined above or is there a better way?
For the record, I'm looking for something along the lines of
bool HasChanged()
{
return this.currentState != this.initialState;
}
not this
bool HasChanged()
{
// this._hasChanged is set to true via event handlers
return this._hasChanged;
}
I'd just rather not have to manage the current state and the initial state myself, I'm looking for a way to grab that info from the BindingSource
If I can get this functionality from the BindingSource
its way more ideal since I will be able to use the functionality on many different data sources, regardless of type, etc.
You'll have to implement the INotifyPropertyChanged
interface from within your object classes, then catch whenever a change occurs through proper event handlers for your type class within your DataSource
BindingSource
property.
The one object offering what you require is the DataSet
, containing both the Original and Current (changed) state of an persistent entity. Then, when one cancels, all you need to call is the Rollback()
method. When one accepts the changes, then a call to the AcceptChanges()
method will do.
Besides the DataSet
, perhaps considering an ORM like NHibernate will do the job for you, plus allowing you to use custom defined objects, instead of a DataSet
. Keeping the ISession
API alive while in your form will allow the ISession to keep track of your changes whatever it may be to whatever object it is, as long as it is know by NHibernate.
Another solution implementing the INotifyPropertyChanged
interface, is at the property setter, you could stock the Original value within a private field or for every property of an object. You could simple have an abstract class with the HasChanges
property return whether each property is as its Original state, then return true or false accordingly.
I have a question regarding our interesting initial discussion. I just want to make sure of one thing. Let's call it language barrier if we like. But publishing the PropertyChanged
event through the INotifyPropertyChanged
interface will also somehow "rollback" an object to its original state. The only detail you had to take care is that if the user says he doesn't want to keep the changes, then reload this CurrentItem from the underlying database via the BackgroundWorker
class and its done! No lagging from your GUI, your user has canceled the changes, and you resetted the object to its default/original state!
Well, I guess here's enough details to make yourself an idea, plus all of the other good answers provided by the others. I am confident you will find your way to accomplish what you want.
Best of success! =)
Will is right, you should implement INotifyPropertyChanged
, ideally in conjunction with IDataInfoError
to get visisble information for your users.
For your Objects to get a state and a notification on Editing, try using the IEditableObject
interface.
All three interfaces are used by default from WinForms and help make the programmers life easier.
Instead of flipping a bit, you could check the state against a snapshot of your initial state.
When you open your detail, you could make a clone of the entity that you are going to modify.
Then, when the user attempts to close the form, you could compare the clone (the entity in its original state) with the modified (or not) entity. If the clone and the entity are not equals, you could prompt the user.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With