Le problematiche più comuni di un'architettura M-V-VM con WPF

5 pagine in totale: <<Indietro 1 [2] 3 4 5 Avanti >>

Interagire con la View dal ViewModel

Dato che il ViewModel contiene le logiche, i comandi e le informazioni di stato è lecito chiedersi come esso possa interagire con l'interfaccia. E' comune infatti dover aprire una finestra di dialogo o notificare con una finestra di dialogo l'avvenuta operazione o un errore. Se è concesso alla View conoscere il ViewModel, non lo è altrettanto nel caso contrario, dato che prima di tutto si avrebbe una referenza circolare e soprattutto si perderebbe la possibilità di testare il codice.

In questi casi la via più semplice per far comunicare il ViewModel con la View consiste nell'esporre un evento nella prima che la seconda poi intercetta. E' un modo quindi per notificare un'operazione o una esigenza, senza conoscere chi soddisferà tale richiesta (e neanche è detto che qualcuno lo faccia).

Si supponga di avere nel proprio ViewModel un comando per la chiusura dell'applicazione esposto tramite proprietà e messo in binding con il pulsante contenuto nella View, come nell'esempio seguente.

<Button Command="{Binding CloseApplicationCommand}" 
  Content="Close" />

La proprietà CloseApplicationCommand è definite usando come di consueto il RelayCommand:

public MainViewModel() 
{ 
    this.CloseApplicationCommand = new RelayCommand(Close); 
} 
public ICommand CloseApplicationCommand 
{ 
    get; 
    private set; 
}

A questo punto è possibile accompagnare tale proprietà con un evento CloseApplication, scatenato all'interno del metodo Close o ogni qual volta si voglia chiudere l'applicazione. Si definiscono perciò l'evento e il relativo metodo per invocarlo secondo i canoni classici del .NET Framework.

public event EventHandler CloseApplication; 
protected virtual void OnCloseApplication(EventArgs e) 
{ 
    if (CloseApplication != null) 
        CloseApplication(this, e); 
}

A questo punto chi si fa carico di chiudere l'applicazione è la View rappresentata dalla finestra principale, la quale intercetta l'evento e chiama il metodo opportuno di chiusura.

public MainWindow() 
{ 
    this.InitializeComponent(); 
 
    MainViewModel mainViewModel = new MainViewModel(); 
    mainViewModel.CloseApplication += (s, e) => this.Close(); 
 
    this.DataContext = mainViewModel; 
}

L'esempio illustrato è minimale, ma può essere esteso anche per mostrare finestre di dialogo o notificare errori. In questi casi può essere necessario estendere la classe EventArgs in modo da ricevere attraverso l'evento informazioni aggiuntive utili alla View o allo scopo di essere valorizzate per il ritorno.

Con la tecnica illustrata si mantengono staccati quindi i due strati rendendo comunque testabile il VM anche se così facendo si hanno delle limitazioni perché in pratica si obbliga a mantenere l'accoppiata View con lo specifico VM . Qualora si volesse offrire la chiusura dell'applicazione anche da un altro VM (di una regione o di una sotto-finestra), si creerebbe una situazione in cui il secondo VM deve mantenere un riferimento al primo per poter invocare l'evento. Oppure, viceversa, si costringerebbe ogni View ad intercettare l'evento CloseApplication anche su altri VM; con o senza una classe base risulterebbe molto difficile individuare ogni istanza. Questa soluzione perciò è valida, ma va considerata l'intera applicazione, valutando se è sufficiente per le proprie esigenze.

5 pagine in totale: <<Indietro 1 [2] 3 4 5 Avanti >>

Attenzione: Questo articolo contiene un allegato.

Contenuti dell'articolo

Commenti

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Segnala su:  Facebook  Messenger  Twitter        |

TUTORIALS

Silverlight

.NET Framework

Accesso ai dati

Architettura e design software

Windows Azure

TOP TEN ARTICOLI
ARTICOLI VIA E-EMAIL

Iscriviti alla nostra newsletter nuoviarticoli per ricevere via e-mail le notifiche!

Iscrivi subito! »»»

MEDIA
IN EVIDENZA
MISC