Salve a tutti!
Piccola premessa, questo post non si pone come obbiettivo quello di spiegare e far comprendere il pattern MVVM, quindi se state cercando una guida che vi introduca a tale pattern questo, per il momento, è il posto sbagliato :)
Girovagando per la rete e dopo varie esperienze personali, sono arrivato alla conclusione che gestire direttamente le view nel nostro ViewModel è probabilmente uno dei task piu complessi del MVVM,piccolo esempio, caso reale :
abbiamo una finestra con due Button, "Chiudi" e "Apri Window2".
Come possiamo aprire e chiudere Windows senza rompere il pattern MVVM ed in contemporanea senza scrivere decine di righe di codice?
Probabilmente la cosa è piu semplice di quanto vi possiate aspettare!
Diamo un'occhiata alle classi e alle view necessaria a compiere l'operazione :
Quindi abbiamo :
- MainWindow.xaml, la nostra prima view
- Window2.xaml, la view che verrà aperta
- WindowViewModel.cs, il nostro ViewModel
- CloseCommand.cs, il command di Chiusura delle Window
- OpenCommand.cs, il command di apertura di una nuova Window
Semplicissima struttura dove il viewModel espone i Command e ogni Command ha una propria funzione, il trucco sta nel passare attraverso l'attributo CommandParameter l'istanza della view corrente potendola gestire nel viewModel e quindi nel metodo Execute del Command.
Vediamo il sorgente del file WindowViewModel.cs :
Il ViewModel implementa l'interfaccia INotifyPropertyChanged ed espone i due Command : OpenCommand e CloseCommand, vediamo subito come sono composti i due Command :
CLOSECOMMAND.CS :
Come possiamo notare, implementa ovviamente ICommand e nel metodo execute elabora un cast del parametro "parameter" (che passeremo attraverso l'attributi CommandParameter) che contiene l'istanza dell View da chiudere.
Da notare che il Cast viene effettuato utilizzando la classe "Window" e non "MainWindow", sfruttando la classe madre è possibile scrivere un'unico Command di chiusura per qualsivoglia view.
Se il cast fosse stato elaborato in questo modo : ((MainWindow)parameter).Close(); al passaggio di una view di tipo "Window2" avremmo ottenuto un bel errore e saremmo stati costretti a creare un'ulterio Command di chiusura per quella specifica view.
OPENCOMMAND.CS :
Valo lo stesso di quanto detto sopra, nel metodo execute istanziamo semplicemente una nuova Window2 e la apriamo tramite il metodo ShowDialog.
Inizializziamo il datacontext con una nuova istanza del nostro ViewModel :
Ora dichiariamo il Button in questo modo :
Chiusura della View :
<Button Content="Chiudi" Height="23" HorizontalAlignment="Left" Margin="40,34,0,0" VerticalAlignment="Top" Width="131" Command="{Binding Path=CloseCommand}" CommandParameter="{Binding ElementName=Window1, Path=.}"/>
Apertura Window2 :
<Button Content="ApriWindows2" Height="23" HorizontalAlignment="Left" Margin="40,76,0,0" VerticalAlignment="Top" Width="131" Command="{Binding Path=OpenCommand}"/>
Notiamo l'attributo Command :
Command="{Binding Path=CloseCommand}"
E l'attributo CommandParameter che passa l'istanza della View (Window1, che poi sarebbe l'attributo Name presente nel tag Window) :
CommandParameter="{Binding ElementName=Window1, Path=.}"
Spero possa esservi stato d'aiuto e.....ci vediamo alla prossima!
Stay Tuned!