2010-08-25 11 views
5

Sto lavorando a un'applicazione Silverlight LoB che i progettisti desiderano avere un'interfaccia a schede, simile all'interfaccia di Visual Studio (probabilmente utilizzeremo i controlli Telerik Rad per le schede di ancoraggio). Avendo fatto un prototipo, l'interfaccia sta funzionando bene finora, ma sto avendo problemi a pensare a come implementare la funzionalità di annullamento/ripristino in un progetto MVVM.Come implementare l'annullamento/ripristino in un'applicazione MVVM?

La funzionalità annullamento/ripristino deve:

  1. On annullamento/ripetizione, ripristinare lo stato di interfaccia utente, cioè fuoco ritorno, selezione ecc controllo (s) (ad esempio una casella di testo) che il cambiamento ha avuto origine da.
  2. avere uno stack per-view undo/redo

In genere, mi piacerebbe utilizzare il modello di comando, ma non sono sicuro di come applicare tale con MVVM.

Ho usato comandando & vincolante per ottenere il idealizzato loose-accoppiamento dei punti di vista & view-modelli, ma rende undo/redo molto più complicato, dal momento che il modello vista non ha alcun concetto della vista e lo stato della vista quando viene ricevuto un comando o viene modificata una proprietà associata. Sembra che io abbia bisogno di un qualche tipo di tracciamento del servizio su quale vista è attiva ogni volta che l'utente esegue un'azione annullabile e ottiene lo stato per il successivo ripristino.

Esiste un consenso su quale sia la migliore pratica per l'imposizione di annullamento/ripristino in MVVM? Ho guardato con interesse a come Daniel Vaughan lo fa nel suo progetto di Calcium; Apparentemente la miscela è stata scritta usando il pattern MVVM e si comporta esattamente come voglio la mia app, sarebbe fantastico se MS avesse spiegato come l'avevano fatto!

risposta

2

La prima cosa che devi fare è assicurarti di separare completamente le azioni dall'interfaccia. Ciò significa trasformare tutte le operazioni che influenzano i dati in azioni discrete. Ciò implica anche che qualsiasi cosa causi un cambio di vista dovrebbe essere registrata come un'azione discreta. Fondamentalmente lo stato dell'interfaccia dovrebbe riflettere solo le modifiche ai dati e le modifiche alla visualizzazione basata sui comandi (vedere la mia ultima nota qui sotto sulla modifica della vista).

I sistemi di annullamento di maggior successo che abbiamo utilizzato in precedenza consentivano l'annidamento di oggetti IUndoableCommand. Questi comandi composti si trasformano in un'azione dell'utente singolo (il tipo di azione che ci si aspetterebbe di visualizzare in un menu Annulla).

Nota che menzioni l'utilizzo di Annulla attraverso le visualizzazioni ... Sembra un comportamento insolito per un'app multiforme. Normalmente l'annullamento è solo all'interno di singoli controlli e per qualsiasi operazione di trascinamento. Le eccezioni sono solitamente interfacce grafiche (non basate su moduli). Cambiare forma durante l'annullamento sarebbe l'equivalente di MS Word passare a un altro documento e continuare a annullare ... piuttosto fastidioso per l'utente finale. Potrebbe volere che l'esperienza dell'utente torni a ripensare a quell'aspetto del design. Solo i miei 2 centesimi.

Spero che questo aiuti.

+0

Ora esaminerò anche il progetto del calcio in base alla tua menzione. Grazie per quello. –

+0

Grazie per la risposta, HiTech. Quando dici "annulla solo all'interno dei singoli controlli" intendi che, ad esempio, in un modulo (vista) con alcuni TextBox, l'utente deve concentrarsi su un TextBox in cui è stato originato un cambiamento per annullare/ripristinare qualsiasi cambiamento che ha fatto tramite quel TextBox? Separare completamente le azioni dall'interfaccia - non significherebbe vietare il binding TwoWay tra i controlli nella vista e le proprietà sul modello di vista? Sfortunatamente, la nostra app ha sia una superficie di disegno interattiva (tela) che forme come Blend/VS; è complesso Sicuramente apprezzo i tuoi pensieri! – JamesCo

1

@JamesCo,

Ho implementato undo/redo per un'applicazione WPF e finito per pubblicare il mio codice di undo/redo a http://muf.codeplex.com/. Puoi anche farlo tramite NuGet. Basta cercare "MUF" o "Monitorare Undo Framework". Include il supporto per Silverlight 4.0, così come .NET 3.5, 4.0 e WP7.

La mia app WPF utilizzava anche MVVM e, in alcuni casi, permetteva di annullare cose come le modifiche alla selezione.Ho anche rintracciato la "pagina" attiva che è stata mostrata nel frame WPF in modo che l'utente sia stato spostato nella pagina in cui deve essere applicata l'azione di annullamento.

La libreria adotta un approccio flessibile su come si codifica l'azione per annullare/ripetere ogni passaggio. In definitiva, basta un delegato per annullare e un delegato per rifare. Puoi fare in modo che questi delegati facciano quello che vuoi. Incluso nella libreria è un'implementazione predefinita che prende semplicemente l'oggetto, il nome della proprietà, il vecchio valore e il nuovo valore. Costruisce delegati basati sulla riflessione che applicheranno i vecchi o nuovi valori secondo necessità.

Per quanto riguarda l'isolamento delle modifiche per ciascuna vista, la libreria consente di mantenere una pila separata di azioni di annullamento/ripristino per ogni "documento" o "contenitore". Basta passare un riferimento al contenitore per ottenere lo stack di annullamento/ripetizione associato.

Infine, la libreria include il supporto per le modifiche di batch insieme. Questo è utile nei momenti in cui più azioni dovrebbero essere annullate insieme come un'unità.

Commenti e domande sono benvenuti nel sito di codeplex (http://muf.codeplex.com/). È anche possibile trovare la documentazione completa e applicazioni di esempio là.