1

I am playing around with the BookShelf demo application by John Papa. And would like to make some adjustments in how a book item is edited. In that application both the BookView and the EditBookWindow is bound to the same ViewModel BookViewModel which is fine.

Selecting a book will cause the EditBookWindow to be opened in a childwindow

private void OnLaunchEditBook(LaunchEditBookMessage msg)
{
    var editBook = new EditBookWindow();
    editBook.Show();
}

If you edit any of the values the data for the selected book will be updated in the BookViewModel. Now this is where the problem occurs. If you press Cancel on the dialogwindow the changes will still persist.

private void OKButton_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = true;
}

private void CancelButton_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = false;
}

What I would like to do is to change this to "rollback" the entity to it's state before you opened the dialogwindow and started editing.

My google search on this issue leads me to think that most efficient (and easy) way of solving this is by using the IEditableObject interface : BeginEdit, EndEdit or CancelEdit.

I'm having trouble figuring out how to implement this interface. As both the EditBookWindow and the BookView is sharing the same ViewModel, the item changed is stored in the property SelectedBook

private Book _selectedBook;
public Book SelectedBook
{
    get { return _selectedBook; }
    set
    {
        _selectedBook = value;
        RaisePropertyChanged("SelectedBook");
    }
}
  1. Is the IEditableObject the most easy approach to my problem?
  2. Can anyone give some pointers on where (ViewModel, Views) and how I could implement the interface?
AxelEckenberger
  • 16,628
  • 3
  • 48
  • 70
Kman
  • 4,809
  • 7
  • 38
  • 62
  • One approach could be to cache a version of the book as a property in the BookViewModel. Using MVVM-light messaging I could send a message back to the BookViewModel if 'cancel' is pressed and then set the selectedBook = _cachedBook ?? Or should I go for a more generic approach? – Kman Jun 28 '11 at 20:21

1 Answers1

2

This is the same problem adressed by this post and the same solution can be applied. :-)

In short create a copy of your model, initialize your detail view with it. Alternatively hold a copy of your model inside your view model, and reset it when cancel is pressed. Or reload the item from the data source on cancel.

Edit:

If you want to use IEditableObject you can save the model on BeginEdit, clear the saved state on EndEdit, and use the saved state to restore the original state on CancelEdit. The usage of the JavaScriptSerializer makes creating backup copies quite easy.

Using IEditableObject is just a variation, but not a completely different concept. With using IEditableObject the model it self is responsible for handling the rollback mechanism. In the first approach the ViewModel is responsible.

If you can edit the Model using IEditableObject is fine, but often you cannot modify the model, e.g. if you model is generated by a proxy when accessing a web service.

Community
  • 1
  • 1
AxelEckenberger
  • 16,628
  • 3
  • 48
  • 70
  • But this solution would not use the IEditableObject which if I am correct would be the best approach to solve this issue. I guess I'll look a bit more into the IEditableObject to see if I can get the hang of how to implement it. If not, then this I'd go towards a solution shown in the linked post – Kman Jun 30 '11 at 15:56