patterncsharpMinor
Easly cancellable operations WPF
Viewed 0 times
cancellablewpfoperationseasly
Problem
Several times we need to be able to revert the data the user is inserting to a previous state (cancel data update). In order to keep DRY and for the sake of separation of concerns I thought about a way of just allowing that.
Some drawbacks of this solution are, but are not limited to:
Any insights of better alternatives? Is this code acceptable?
public class RevertableObject : ViewModelBase //implements INotifyPropertyChanged
where T:class, ICloneable
{
public RevertableObject(T initialValue)
{
Value = initialValue;
Value = initialValue.Clone() as T;
}
private T _oldValue;
private T _currentValue;
public T Value
{
get { return _currentValue; }
private set
{
_oldValue = _currentValue;
_currentValue = value;
OnPropertyChanged();
}
}
public void Revert()
{
Value = _oldValue;
}
}Some drawbacks of this solution are, but are not limited to:
- Dependency on the interface
ICloneablewhich does not have a way of knowing the cloning algorithm being used (member clone vs deep clone)
- It only allows one object to be reverted once.
Any insights of better alternatives? Is this code acceptable?
Solution
You could empower
UPDATE: I do not feel right by copy-pasting that article, so I would still recommend to have a look at it. Quick test though might look like the following:
1) Download and reference
2) Create model:
3) Create view model (I used
4) Update
It works :)
IEditableObject. Here is a good article. Approach described will allow your model to do not mix concerns - they use memento design pattern.UPDATE: I do not feel right by copy-pasting that article, so I would still recommend to have a look at it. Quick test though might look like the following:
1) Download and reference
BindingOriented.Adapters project in your WPF application.2) Create model:
public class Contact
{
public string Name { get; set; }
}3) Create view model (I used
MvvmLight for RelayCommand):public class MainViewModel
{
public MainViewModel()
{
Contact = new EditableAdapter(new Contact() { Name="Dmitry" });
OKCommand = new RelayCommand(() => Contact.EndEdit());
CancelCommand = new RelayCommand(() => Contact.CancelEdit());
}
public EditableAdapter Contact { get; }
public ICommand OKCommand { get; }
public ICommand CancelCommand { get; }
}4) Update
MainWindow to include:
It works :)
Code Snippets
public class Contact
{
public string Name { get; set; }
}public class MainViewModel
{
public MainViewModel()
{
Contact = new EditableAdapter<Contact>(new Contact() { Name="Dmitry" });
OKCommand = new RelayCommand(() => Contact.EndEdit());
CancelCommand = new RelayCommand(() => Contact.CancelEdit());
}
public EditableAdapter<Contact> Contact { get; }
public ICommand OKCommand { get; }
public ICommand CancelCommand { get; }
}<StackPanel>
<StackPanel.DataContext>
<vm:MainViewModel/>
</StackPanel.DataContext>
<TextBox Text="{Binding Contact.Name}"/>
<Button Content="OK" Command="{Binding OKCommand}"/>
<Button Content="Cancel" Command="{Binding CancelCommand}"/>
</StackPanel>Context
StackExchange Code Review Q#118322, answer score: 4
Revisions (0)
No revisions yet.