tags:

views:

572

answers:

4

How can I implement cancelation of editing an object using MVVM.

For example: I have a list of customers. I choose one customer an click the button "Edit", a dialog window(DataContext is binded to CustomerViewModel) opens and I start editing customer's fields. And then I decide to cancel editing, but the fields of the customer have been already changed, so how can I return a customer to its previous state in MVVM?

+2  A: 

Check out the IEditableObject interface. Your Customer class should implement that, and your commands can execute BeginEdit / CancelEdit / EndEdit as appropriate.

HTH, Kent

Kent Boogaart
@Kent Boogaart IEditableObject creates a lot of overhead for your objects, especially if your Model objects are a Class and not a Struct, you would have to rewrite your model objects to support it.
Agies
@Agies: Why the downvote? Whether IEditableObject is a "lot of overhead" or not depends entirely on your infrastructure or how you want to implement it. It's just an interface that WPF understands. How you implement it is up to you.
Kent Boogaart
+1  A: 

In this article, Raul just reload the object from the DB. I guess it's less trouble than the solution Kent proposes.

    internal void Cancel(CustomerWorkspaceViewModel cvm)
    {
        Mainardi.Model.ObjectMapping.Individual dc = cvm.DataContext 
                                 as Mainardi.Model.ObjectMapping.Individual;

        int index = 0;

        if (dc.ContactID > 0 && dc.CustomerID > 0)
        {
            index = _customerCollectionViewModel.List.IndexOf(dc);
            _customerCollectionViewModel.List[index] = 
                                  _customerBAL.GetCustomerById(dc.CustomerID);
        }

        Collection.Remove(cvm);
    }
Eduardo Molteni
I think reloading from the DB is one way of fulfilling the obligations of the IEditableObject of mr Boogaarts suggestion, not necessarily an alternative to the same.
Guge
A: 

You could also, in your ViewModel copy the model's state to internal fields, and then expose these and then only set them on the model, when the user actually commits the change.

Problem could be, that on-the-fly validation will be more troublesome if validation relies on the entity being updated - if this is a requirement you could create a clone of the model to work on and then merging the clone with the actual entity when it is saved.

Goblin
A: 

One super easy way, if your object is already serializable, such as if you are using WCF. You can serialize your original object into an internal field. If, your object isn't serializable, then just use AutoMapper to create a copy of your object with one line of code.

Order backup = Mapper.Map<Order, Order>(order);

When you handle your CancelCommand, just call AutoMapper in reverse. Since your properties already have a change notification everything just works. Its possible you could combine these techniques with IEditableObject, if you need and want to write the extra code.

Agies