Sasha
Sasha

Reputation: 853

On clicking CancelBtn cancel changes

I have in my program custom property grid, where all properties are bindable from viewModel. In this property grid there are also 2 buttons - SaveBtn and EditBtn. User edit properties in property grid. When SaveBtn is clicked, all properties must be saved in a database. If user wants to edit properties, he clicks EditBtn and then before saving properties to database(SaveBtn is clicked), should appear new window, where user chooses a reason of modification of a properties. On that window there are also three buttons - ExitWithSavingToDatabase, ExitWithoutSavingToDatabase and Cancel.

If user chooses Cancel, all changes should be canceled. But properties in viewModel already have new values. My question is - how can I reset properties to old values??? I was thinking of reloading properties from database, but if there is a better solution, where I can do it without using database?

Upvotes: 0

Views: 1099

Answers (2)

Samuel
Samuel

Reputation: 6490

A probably better way to go is to use only the values from the binding group, not the model. This supports binding transaction commit/abort Define a binding group for your window

  <Window.BindingGroup>
    <BindingGroup >
      <BindingGroup.ValidationRules>
        <local:YourValidationClass/>
      </BindingGroup.ValidationRules>
    </BindingGroup>
  </Window.BindingGroup>

YourValidationClass should handle the validation of a BindingGroup, not a single value. Important always use GetValue from the BindingGroup here, not from the Model, the Model is not modified yet

public class YourValidationClass : ValidationRule
  {
      public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
      {
          BindingGroup bindingGroup = (BindingGroup)value;

          if (bindingGroup.Items.Count == 1)
          {
              User user = (User)bindingGroup.Items[0];
              string firstName = (string)bindingGroup.GetValue(user, "FirstName");
              string lastName = (string)bindingGroup.GetValue(user, "LastName");

              if (string.IsNullOrWhiteSpace(firstName) || string.IsNullOrWhiteSpace(lastName))
              {
                  return new ValidationResult(false, "Both fields required");
              }
          }
          return ValidationResult.ValidResult;
      }
  }

Your cancel button should then execute the following code:

this.BindingGroup.CancelEdit();

Your Save button should at least do

this.BindingGroup.CommitEdit();

to bind the group values to the model.

Upvotes: 2

Dennis
Dennis

Reputation: 37780

There are number of approaches:

  1. One of the you've mentioned - just throw away modified object and get new one with unchanged properties from store.
  2. Memento/Caretaker pattern. Memento is an object, that takes the snapshot of original values, and Caretaker is an object, that can rollback changes, using snapshot, stored in Memento (also, you may consider Undo/Redo as an evolution of this pattern).
  3. You could modify a copy of object, and if the user wants to save changes, you should apply property values from copy to original. This requires object-to-object mappers (e.g. Automapper), as the manual copying of property values is error prone.

Upvotes: 1

Related Questions