Best way to check if a Model has changed in a ViewModel?

Topics: Questions
Jul 29, 2012 at 4:13 PM

I have a CustomerViewModel and a Customer (model).

The Customer (model) is a property on the CustomerViewModel and exposes the model properties through the use of the Expose attribute.

In the constructor of the CustomerViewModel the Customer is fetched from the repository.

In the Save of the ViewModel I would like to know if the properties of the model have been changed (though input of the user in the datawindow which displays the customer).

Is there a way in Catel to detect if the model has been changed? The 'IsDirty' property seems to be 'true' as soons as the Customer propery is assigned (in the viewmodel constructor) so ít seems I can't use this property. Is there another way?

Regards,
Peter

 

Coordinator
Jul 29, 2012 at 4:33 PM

Catel cannot do this for you. The IsDirty is for the ViewModel, not for the Model. If your model was using DataObjectBase, you could use the IsDirty on that one. If you are using EF entities as models, you have to check yourself.

Jul 29, 2012 at 8:19 PM
Edited Jul 29, 2012 at 8:28 PM

My model classes are POCO's who inherit from DataObjectBase and are read using EF.

The IsDirty on the Model is always true.
When using the ObjectStateManager the state of the modified entity is always unchanged although changes have been made to the properties of the model.

So nothing seems to work :(

Update: Found out why ObjectStateManager does not return the entity as modified: the state is only updated after DetectChanges is called. And this is not called before the SaveChanges on the DbContext.

If I manually call DetectChanges, it works and the entity state is Modified. However, to call DetectChanges for every time I need to check if a model is dirty, is perhaps a bit expensive?

Coordinator
Jul 29, 2012 at 8:41 PM

Depends on when you need to check for changes. What is your business case?

Jul 29, 2012 at 8:46 PM
Edited Jul 29, 2012 at 8:47 PM

When the user pressed the cancel button in a data window, I want to check if any changes have been made to the model by the user. If so, then inform the user he is about to lose his changes and give him the opportunity to cancel the cancel.

I guess, it should be okay to call DetectChanges when this occurs, because the frequency of such events won't be very high.

Coordinator
Jul 29, 2012 at 8:47 PM

Exactly, especially with the new feature where you can cancel the canceling of the view model :)

Jul 29, 2012 at 8:51 PM

Indeed! Used that feature today and it works very nice indeed :)

Although I still had to create my own subclass of DataWindow, because the DataWindow ignores the possibiliy to cancel a view model (perhaps in a next release? ;) )

 

Coordinator
Jul 29, 2012 at 8:52 PM

Hmmm, good point, it doesn't respect it yet. I will create a work item for that.

Coordinator
Jul 30, 2012 at 7:47 AM

You might want to try the latest package, should contain a fix.

Jul 30, 2012 at 12:32 PM

Thanks for the fix. Unfortunately, I can't use it because I use custom buttons. This is only because I want to use A Save button instead of OK. I don't know how I can 'rename' the default button. And I can't reuse the OnOkCanExecute, OnOkExecute etc. methods either, because they are not protected but private.

Coordinator
Jul 30, 2012 at 4:15 PM

You can use the DataWindow with Custom buttons and still use the OK behavior in the next release:

    class DataWindowEx : DataWindow
    {
        public DataWindowEx()
            :base(DataWindowMode.Custom)
        {
            AddCustomButton(new DataWindowButton("Save", OnOkExecute, OnOkCanExecute));
        }
    }
I made them protected instead of private.

Jul 30, 2012 at 5:24 PM

Great! This will also solve the Cancel method being called twice (http://catel.codeplex.com/discussions/387848) :)