In MVVM, ViewModel o View dovrebbe essere responsabile della creazione di nuove viste?

7

Nella mia applicazione WPF, voglio creare una nuova vista. Dove dovrei farlo - in ViewModel o Modello ?

L'applicazione è uno (molto semplice per ora) strumento simile a una finestra con un singolo pulsante "invia". Nel caso in cui una delle caselle di controllo sia selezionata, dovrebbe apparire una nuova finestra utilizzando lo stesso ViewModel per chiedere all'utente ulteriori dettagli. Ai fini di questa domanda, consideriamo solo l'approccio alla nuova finestra senza considerare altri approcci come il pannello mostrato / nascosto.

Idealmente, in View non dovrebbe esserci alcun codice. Inoltre, poiché View non ha alcuna logica in essa, la VM dovrebbe inizialmente verificare se è necessaria la creazione di una nuova vista e, quando lo è, rimandare questa responsabilità alla vista, portando a code bloat.

D'altro canto, la creazione di una nuova vista in ViewModel viola il principio che ViewModel non dovrebbe sapere nulla su View.

Quindi è meglio creare nuove viste in View o ViewModel?

    
posta Mac70 12.09.2016 - 14:44
fonte

2 risposte

6

Uso l'iniezione di dipendenza e una IViewFactory iniettata nel modello di visualizzazione per rispettare entrambi i vincoli.

Un ProductViewModel (ad esempio) chiama this.viewFactory.Show("Details", this) per aprire ProductDetailsView con se stesso come ProductViewModel . Potrebbe anche aprire una vista basata su un altro modello di vista con this.viewFactory.Show<ClientViewModel>() .

L'implementazione (ce ne sono diversi per WinForms, semplice Wpf Windows, una shell Wpf con schede, ...) si basa su una convenzione StructureMap . Le viste designano il loro modello di visualizzazione tramite un'interfaccia IView<ProductViewModel> .

Quindi il modello di vista non sa nulla della vista tranne il suo ruolo (vista predefinita, vista dettagli, ...), e la vista non contiene codice per creare un'altra vista. Inoltre, i modelli di viste si trovano in un assieme separato che non fa riferimento a nessun assembly Wpf.

    
risposta data 12.09.2016 - 21:16
fonte
5

Risposta teorica

Se hai una ViewModel , le azioni che hanno effetti estetici (es. evidenziano un oggetto al passaggio del mouse) sono il lavoro di View , mentre le azioni che hanno effetti "reali" (ad esempio, generazione di una nuova finestra) sono lavoro del ViewModel .

Pertanto, la creazione di una nuova finestra è un lavoro per ViewModel . Tuttavia, né la Visualizzazione né la ViewModel dovrebbero sapere esattamente come creare una Finestra, che non fa parte delle loro responsabilità e appartiene a una classe diversa.

Si potrebbe sostenere che la creazione di una nuova finestra è un lavoro per View . Anche se non sarei d'accordo, c'è poco valore in un tale dibattito, perché in pratica non è la fine del mondo se si colloca quel codice in View , e anche non è molto lavoro spostarlo nella ViewModel in un secondo momento. La parte importante è che la logica per la creazione di una nuova finestra è contenuta in una classe indipendente, solitamente una sorta di WindowFactory. Il punto di MVVM, MVP, MVC, ecc. È che hai classi con poche e ben definite responsabilità. Ecco perché non aggiungi responsabilità aggiuntive a View , ViewModel o Model se non è necessario.

In nessun caso la creazione della Finestra appartiene a Model , perché Model non è nemmeno a conoscenza dell'esistenza di qualcosa come una GUI.

Risposta pratica

Si tratta di uno "strumento simile a una finestra con un singolo pulsante" invia "" . Quindi, ecco un plug sfacciato per una mia risposta correlata: Perché utilizzare MVVM?

Per riassumere ciò che dice la risposta: Keep it simple. Oh, e tieni presente la risposta teorica di cui sopra per implementare una volta che la tua finestra a pulsante singolo inizia a diventare più complessa.

    
risposta data 12.09.2016 - 22:17
fonte

Leggi altre domande sui tag