Oggi pomeriggio ho messo in pratica l'idea che mi
frullava in testa da un po' di tempo, ovvero implementare all'interno di una mia
applicazione un meccanismo riutilizzabile di undo e redo. In altre
parole, immaginate di avere un business object
qualsiasi, che viene bindato attraverso un BindingSource a diversi controlli sulla Windows Forms. L'utente
può ovviamente editare i controlli, aggiornando di conseguenza il business
object sottostante. Ogni volta che l'utente modifica qualcosa, si scatena
l'evento CurrentItemChanged, nel caso
scatto una fotografia dell'oggetto chiedendo un memento all'originator,
ovvero il business object stesso.
I memento vengono salvati in una lista tipizzata
(BindingList<Memento>), che mi servono per mantenere uno storico di tutti
i cambiamenti che l'utente ha fatto sul business object. Fatto questo, il passo
seguente è stato semplice ed indolore: ho aggiunto un pulsante
btnUndo che mi permette di annullare una certa modifica
che l'utente ha fatto. Ogni volta che lo clicco, recupero il memento dalla lista, e chiedo al business object di
usarlo per ritornare allo stato precedente.
Il business object implementa l'interfaccia
IMementoCunsumer, che mi sono inventato di sana pianta, che
richiede due soli metodi:
public interface IMementoConsumer
{
void SetMemento(Memento m);
Memento CreateMemento();
}
Tutti gli oggetti che implementano tale interfaccia, devono:
- avere un metodo SetMemento, per ritornare ad uno stato
precedente. Lo stato è dato dall'oggetto Memento, una classe
astratta dalla quale derivano tutti i memento specifici del contesto
nel quale ci troviamo
- avere un metodo CreateMemento che ritorna un oggetto
Memento, che eventualmente servirà all'oggetto stesso per
recuperare uno stato precedente
Ultima nota: all'interno della Windows Forms ho definito una variabile int _historyPosition. Mi serve come puntatore all'interno
della lista tipizzata: quando faccio un undo, viene decrementata.
Quando faccio un Redo (il contrario di Undo,
ovviamente), tale variabile viene incrementata.
Grazie a Luca Minudel per avermi dato qualche dritta nel mio post di qualche giorno fa.
powered by IMHO 1.3