Memento and collections

Adding the ability to undo and redo collection changes on a collection is very simple using the CollectionChangeUndo class. This can be done either automatically or manually.

Handling collection changes automatically

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

var mementoService = ServiceLocator.Instance.ResolveType<IMementoService>();
mementoService.RegisterCollection(myCollection);

Handling collection changes manually

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

public void AddPerson(IPerson person)
{
    var newIndex = _internalCollection.Add(person);
    
    var mementoService = ServiceLocator.Instance.ResolveType<IMementoService>();
    mementoService.Add(new CollectionChangeUndo(_internalCollection, CollectionChangeType.Add, -1, newIndex, null, item)); 
}

Note that all actions should be implemented, such as adding, replacing, removing and resetting to fully support undo/redo

Removing a collection and its actions

When a collection 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 collection:

var mementoService = ServiceLocator.Instance.ResolveType<IMementoService>();
mementoService.UnregisterCollection(myCollection);

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