8

I have a Window that serves as a dialog in a WPF application. This dialog has an "OK" and a "Cancel" button. I am setting the DataContext of the Window to an instance of an object in my application. The user can change the values of the properties of the object within the Window. If a user clicks "Cancel", I want to revert the property values back to their original values. Is there an easy way to do this in WPF?

For instance, I know with RIA data services there is RejectChanges. Is there something similar on the client-side with WPF?

Thanks!

Phone Developer
  • 1,411
  • 4
  • 25
  • 36

2 Answers2

3

In object which is set to DataContext (ideally it should be ViewModel in MVVM approach) expose two commands

public ICommand CancelCommand { get; set; }
public ICommand OkCommand { get; set; }

Then for the buttons assign these commands like shown below

<Button Command="{Binding CancelCommand}" ... />

You've to keep two copies of object, a copy should be created by Deep Copy or if an object has a few editable fields you can keep those as class fields. Basically on initialization stage do backup editable object properties, then bind to DataContext editable version of object. In Cancel Command handler - restore from a backup copy...

Community
  • 1
  • 1
sll
  • 61,540
  • 22
  • 104
  • 156
  • 4
    And .NET defines the `IEditableObject` interface for exactly this purpose. When the dialog opens you would call `BeginEdit`. When it is closed, you call either `EndEdit` or `CancelEdit` depending on which button is clicked. – Kent Boogaart Nov 10 '11 at 07:29
  • 1
    Yes, you can maintain old state of object beginedit than if correct than applyedit or endedit and if reject changes by CacelEdit – Nakul Chaudhary Nov 10 '11 at 07:52
  • 1
    @Kent Boogaart : Hi Kent! Thanks for pointing to this. Are there any benefits by using this built in interface? Or just following standard approach? Also, from MVVM perspectives how it could be used to tie button click with the restore state logic? – sll Nov 10 '11 at 08:39
  • 3
    The advantage (other than being standard) is that controls that support `IEditableObject` (such as `DataGrid`) will automatically invoke it on your behalf. You could create your own base class for dialogs that also look for `IEditableObject` and calls its methods as appropriate. Otherwise, you can just have your VM do it - your command to open the dialog would invoke BeginEdit and it would invoke one of the other two methods depending on the dialog result. You would do all this through a window management service so as to keep your VM independent of any view concerns. – Kent Boogaart Nov 10 '11 at 12:31
  • 1
    @Kent Boogaart : Great stuff! Thanks! I will take a look into, definitely I want to understand how it works especially how/when controls able to invoke it's memmbers on my behalf automatically (Also i newer heard about windows management service, so a lot of stuff to go over). Thanks! – sll Nov 10 '11 at 13:09
2

When the object is simple (just a few properties of basic types such as string, int, etc.) DeepCopy or IEditableObject is a very good option.

When the object is a node in a more complex hierarchy this might prove to be too difficult and going back to the server/model and reloading the original data is much easier.

Emond
  • 50,210
  • 11
  • 84
  • 115
  • I believe Deep Copy (either vie serialization or reflection) could handle any comple Node, am I wrong? I believe server call is much expensive anyway, because you already have an object in memory so do with it what you want and it woudl be (I believe) less expensive rather than network request/response – sll Nov 10 '11 at 13:33
  • `IEditableObject` does not stipulate how you go about implementing the edit/commit/rollback behavior. It could be that you're serializing/deserializing behind the scenes, or you're just copying fields about, or you're going back to the server/database to refresh data objects. A complex hierarchy doesn't preclude you from implementing `IEditableObject`. – Kent Boogaart Nov 10 '11 at 13:40
  • 1
    I am not suggestion that it is not possible, I am only suggesting that it can become quite difficult depending on the complexity of the object tree. And yes, DeepCopy is a way to implement IEditableObject – Emond Nov 10 '11 at 15:00