Domanda

Supponiamo che, un modulo di vincita abbia determinati campi di input e l'utente inserisca / reinserisca alcuni dati.

Come conservare i dati precedentemente immessi dall'operazione 'annulla'?

Voglio solo sapere il modo migliore per realizzarlo.

È stato utile?

Soluzione

Ci sono alcune opzioni. L'importante è che inizi a progettarlo all'inizio del progetto. Cercare di aggiungerlo a un progetto esistente può essere molto costoso se non è stato progettato pensando a questa capacità.

Ci sono alcuni schemi fondamentali che vorresti sfruttare:

  1. MVC o modello di osservatore . La prima chiave non è tanto l'implementazione religiosa o zelante della tua architettura di alto livello. Ciò che è è che il tuo software riconosce la differenza tra il suo stato attuale e quello visualizzato e si disaccoppia in modo appropriato. È necessario un accoppiamento comune e chiaramente definito tra lo stato visivo e lo stato dell'applicazione. Questo ti fornisce l'architettura comune di cui hai bisogno per creare un comando (vedi # 2).

  2. Il modello Command . Ottieni un sacco di qualità con il modello di comando (anche se può arrivare al costo di alcuni codici che sembrano generati da una procedura guidata). L'approccio specifico adottato per il modello di comando può variare (una classe per comando con implementazione tramite sostituzioni rispetto a una classe per molti comandi con implementazione tramite gestori di eventi, ad es.), Ma i comandi sono " azione " classe che @Ralph ha suggerito di strutturare in pila.

    Questo può essere un po 'complicato, ma l'approccio generale sarebbe quello di ascoltare un evento che "commetterebbe". dati dallo stato visivo allo stato dell'app. Il Validated potrebbe essere un buon hook per un Textbox . Il Fai clic avrebbe più senso per un Button . Quando si verifica tale commit, si crea il comando associato a quel controllo, si tenta di eseguire il comando e si aggiunge il comando allo stack di annullamento se il comando viene completato correttamente. Ora stai monitorando esattamente cosa sta succedendo ed esattamente i dati con cui sta accadendo.

  3. Il modello Memento . @JP Estratto l'ultimo pezzo del puzzle. È possibile utilizzare un ricordo sul comando salvato per memorizzare lo stato del controllo interessato prima dell'esecuzione del comando. Questo, combinato con un membro UnExecute () sull'interfaccia del tuo comando, dovrebbe essere l'ultimo elemento chiave del design necessario per eseguire il tuo compito.

La cosa bella di un approccio strutturato come questo è che ora hai un punto di estensione naturale per un comportamento aggiuntivo che deve avvenire a livello di comando. Le transazioni sono naturali, ad esempio. Nel mio attuale progetto, sto usando il codice WPF < > Interfaccia ICommand (nel mio progetto Winforms) per fornire feedback sul fatto che un determinato comando CanExecute () in qualsiasi momento. Ciò mi consente di abilitare e disabilitare i widget dell'interfaccia utente in modo appropriato in un modo puramente guidato dai comandi. :)

La cosa spiacevole è che non c'è molto supporto per questa struttura integrata in Winforms (per quanto ne so), quindi dovrai costruirne la maggior parte da zero. Nessun singolo pezzo è particolarmente complicato, ma puoi ritrovarti a generare una discreta quantità di codice prevalentemente a caldaia per ogni comando. È anche una tecnica di progettazione pervasiva. Perché sia ??efficace, deve essere utilizzato in modo coerente nelle parti appropriate dell'applicazione. Ciò rende l'adeguamento delle funzionalità piuttosto costoso, soprattutto se il codice originale è strettamente accoppiato e incoerente.

Altri suggerimenti

Non sono sicuro che WinForms / .Net abbia qualche tipo di funzionalità di annullamento integrata di cui puoi trarre vantaggio. Ma quello che stai veramente cercando è una struttura di dati Stack che ti aiuti a gestire un elenco di azioni. Dovrai creare un tipo di "azione" oggetto per rappresentare le azioni che un utente potrebbe fare e man mano che avanzano nell'applicazione dovrai spingere queste azioni sullo Stack. Quando premono il pulsante Annulla, o Ctrl-Z o qualsiasi altro metodo per avviare l'azione di annullamento, salterai l'azione corrente e ripristinerai lo stato dell'applicazione all'azione precedente.

Questa è una panoramica di base e di alto livello di come funzionerebbe, ma immagino che l'implementazione di una tale funzionalità possa diventare piuttosto complessa. Immagina come deve funzionare per un programma come Adobe Photoshop. : O

Questo potrebbe non essere il modo migliore per farlo a seconda di ciò che stai cercando di realizzare, ma potresti usare un richtextbox e invocare il metodo di annullamento incorporato in quel controllo.

Ad esempio:

richTextBox1.Undo();

Questo e questo potrebbe aiutare.

CTRL + Z funziona su singoli controlli.

Se lavori con dati e una BindingSource, puoi " annullare " le modifiche non persistenti ai record chiamando il Annulla Modifica o in alternativa puoi ricaricare i dati per il database.

Il mio suggerimento è di determinare i requisiti di annullamento specifici e i suoi vantaggi pratici prima di iniziare la progettazione e l'implementazione. Ho ereditato un'app WinForms che utilizzava un annullamento sequenziale di più operazioni tramite una pila di "azione" generica oggetti internamente. Tuttavia, si è scoperto che nessuno degli utenti dell'app con cui ho parlato non ha utilizzato la funzione! E il modo in cui funziona questa particolare app, se fossi un utente dell'app, non mi vedrei nemmeno usando la funzione.

La funzionalità Annulla avrebbe potuto essere più utile in questo caso se si fosse trattato di un annullamento 'selettivo'; dove l'utente poteva selezionare qualsiasi singola operazione / modifica di diverse modifiche precedenti apportate, prima del commit dei dati, e ripristinare quella singola modifica al suo stato originale, invece di essere in grado di annullare solo l'ultima operazione prima, seguita dalla seconda all'ultima operazione , ecc., ecco come è stato implementato.

In ogni caso, l'app contiene quindi complessità e riferimenti indiretti non necessari, rendendo più difficile e più lento il "grok" e apportando modifiche e miglioramenti alle funzionalità esistenti, in questo caso per un beneficio scarso o nullo nel mondo reale. Da quando ho ereditato il progetto, ho implementato nuove funzionalità senza annullamento e nessuno ha avuto lamentele.

Potresti anche trovare utile la libreria Reversi, come molti altri sembrano avere. Vedi [ http://www.codeproject.com/KB/dotnet/ reversibleundoredo.aspx] [1] o [this] [2]

[1]: http://www.codeproject.com/KB/dotnet /reversibleundoredo.aspx Rendi reversibile la tua applicazione per supportare Annulla e Ripeti

[2]: http://www.codeproject.com /script/Articles/Article.aspx?aid=22502 Annulla Ripristina

Dipende da quanti livelli di annullamento desideri avere.

Puoi memorizzare i valori prima che vengano "impegnati". in un certo senso in una raccolta a livello di modulo per ciascuno dei controlli, che puoi " ripristinare " al clic di un pulsante affinché l'utente possa tornare indietro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top