WPF – Editing Mode with Save and Cancel Capability – Dynamic ViewModelProxy

July 23, 2010

tags: ,
no comments

Update 29/07: The project was updated, there was a minor bug in the object changed notifier.

In continuation of a previous post –
WPF – Editing Mode with Save and Cancel Capability

In this post I will demonstrate an elegant and simple solution that you can utilize regarding the first option presented in the previous post.

The Use-Case

If you want to open an editable view over an existing read-only view with cancel capability, you usually wish you could use the same ViewModel instance as the DataContext.
However, this means that changes are reflected in the read-only view, plus, how would you implement the cancel operation?

The following solution demonstrates a dynamic proxy that I had written that you can use to provide elegant solution in cases where your ViewModel is simple.
By ‘simple’ I mean the ViewModel contains a set of self-contained properties (their setters don’t affect anything else) and that there are no commands needed for the editable view.

The common approach for such simple cases is defining the bindings with UpdateSourceTrigger set to ‘Explicit’.
My solution is simpler, it doesn’t require you to do that, thus you need not update the bindings upon save and such.
Moreover, my solution still provides a way to support IDataErrorInfo on the ViewModel!

The right pane contains the read-only view:
image
When clicking Edit, a dialog is shown:

image

Let’s see the code

When the user clicks ‘Edit’, the code opens the dialog with the DataContext set as follows –

Code Snippet
var proxy = new ViewModelProxy<EmployeeViewModel>(emp);
editView.DataContext = proxy;

When the user chooses Save or Cancel in the dialog, the following code merges the changes into the actual EmployeeViewModel –

Code Snippet
bool? result = editView.ShowDialog();

if (result.GetValueOrDefault())
{
    proxy.AcceptChanges();
}

That is all that is needed! Nothing else!
The proxy has another method – ‘RejectChanges’ if you need to reject the changes and go back to the state of the original EmployeeViewModel.

How is the magic done?

I implemented the ViewModelProxy using the DynamicObject that comes with .NET 4.0, sweet.
This can be done in previous .NET framework versions too. It would require more code though, you could implement a dynamic property bag with a type descriptor.

The ViewModelProxy performs mainly the following parts –

  1. When a property is set on it – it stores it into a local dictionary and notifies upon property changed
  2. When a property is requested from it – returns the value from the local dictionary if present, or from the source ViewModel otherwise.
  3. AcceptChanges applies the local dictionary values to the source ViewModel
  4. RejectChanges clears the local dictionary and notifies upon property changes.
  5. I mentioned it above, my solution supports IDataErrorInfo, make sure to check out the sample

You can download the source here – Zuker.WpfSamples.zip.

In the next post I will demonstrate another infrastructure I had implemented that you can use for more advanced scenarios.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*