Memento and properties

Adding the ability to undo and redo property changes on an object is very simple using the PropertyChangeUndo class. This can be done either automatically or manually.

Handling property changes automatically

When an object implements the INotifyPropertyChanged interface, it is possible to register the object. The IMementoService will fully take care of any property changes by the object and add these automatically to the undo/redo stack. Internally, the service will create an instance of the ObjectObserver which will register the changes in the IMementoService.

var mementoService = ServiceLocator.Instance.ResolveType<IMementoService>();
mementoService.RegisterObject(myObject);

Handling property changes manually

When an object does not support the INotifyPropertyChanged interface or you want more control, it is possible to instantiate the PropertyChangeUndo yourself. See the example below:

public string Name
{
    get { return _name; }
    set
    {
        object oldValue = _name;
        object newValue = value;

        _name = value;

        RaisePropertyChanged("Name");

        var mementoService = ServiceLocator.Instance.ResolveType<IMementoService>();
        mementoService.Add(new PropertyChangeUndo(this, "Name", oldValue, newValue)); 
    }
}

Removing an object and its actions

When a model goes out of scope, it is important that the IMementoService does not keep it in memory and keeps undoing the changes. Therefore, one should also unregister the object:

var mementoService = ServiceLocator.Instance.ResolveType<IMementoService>();
mementoService.UnregisterObject(myObject);

Note that unregistering an object will both cancel change notifications and remove the actions that belong to this object from the undo/redo stack