Come utilizzare MVVM in un'applicazione Windows universale

Il pattern Model-View-ViewModel (MVVM) aiuta gli sviluppatori a separare la logica di business e di presentazione dell'applicazione dall'interfaccia utente. Mantenere una netta separazione tra logica applicativa e interfaccia utente aiuta a risolvere i problemi di sviluppo e progettazione, rendendo l'applicazione più facile da testare, mantenere e sviluppare. Può anche migliorare la riusabilità del codice e consente a più sviluppatori di collaborare più facilmente quando si lavora sullo stesso progetto.

1. Introduzione

Utilizzando il pattern MVVM, l'interfaccia utente dell'applicazione e la presentazione e la logica di business sottostanti sono separate in tre componenti:

  • Il vista componente incapsula l'interfaccia utente e la logica dell'interfaccia utente.
  • Il guarda il modello componente incapsula la logica e lo stato della presentazione.
  • Il modello layer incapsula la logica e i dati aziendali dell'applicazione.

Esistono diversi framework disponibili per l'implementazione del pattern MVVM in un'applicazione Windows. Qual è la struttura migliore per il tuo progetto dipende dalle tue esigenze. Per questo tutorial, utilizzeremo MVVM Light, un framework MVVM popolare e di facile utilizzo.

Questo tutorial mostra come creare un'app universale per Windows con il supporto MVVM Light. Imparerai come:

  • crea un'app per Windows universale e aggiungi il supporto per MVVM Light
  • implementare la struttura delle directory
  • aggiungi il livello del modello di vista
  • collegare il contesto dei dati
  • implementare il servizio di messaggistica per passare messaggi tra i modelli di visualizzazione

2. Impostazione del progetto

Passaggio 1: creare un'app per Windows universale

Iniziamo creando un'app per Windows universale. Selezionare Nuovo progetto dal File menu in Visual Studio. Espandere Modelli > Visual C # > finestre > Windows 8 > universale e selezionare App vuota (Universal Windows 8.1) dalla lista dei modelli di progetto. Dai un nome al tuo progetto e clicca ok per creare il progetto.

Questo crea due nuove app (Windows Phone 8.1 e Windows 8.1) e un progetto condiviso. I progetti Windows Phone 8.1 e Windows 8.1 sono progetti specifici della piattaforma e sono responsabili della creazione dei pacchetti dell'applicazione (.appx) destinati alle rispettive piattaforme. Il progetto condiviso è un contenitore per il codice che viene eseguito su entrambe le piattaforme.

Passaggio 2: aggiungere il supporto MVVM Light

Fare clic con il tasto destro del mouse sul nome della soluzione nel file Esploratore di soluzioni e selezionare Gestisci pacchetti Nuget per soluzione.

Seleziona il Navigare scheda e cerca MVVM Light. Seleziona il pacchetto MvvmLightLibs dai risultati della ricerca. Controllare entrambi i progetti di Windows 8.1 e Windows Phone 8.1 e fare clic Installare per aggiungere le librerie di MVVM Light alle app.

A questo punto, hai aggiunto il supporto MVVM Light a entrambe le tue applicazioni.

3. Struttura del file di progetto

Un'app di Windows universale che adotta il modello MVVM richiede una particolare struttura di directory. La seguente istantanea mostra una possibile struttura di file di progetto per un'app di Windows universale.

Lascia che ti guidi attraverso la struttura del progetto di una tipica app di Windows Univesal che adotta il pattern MVVM:

  • controlli: Questa directory contiene controlli dell'interfaccia utente riutilizzabili (viste indipendenti dall'applicazione). I controlli specifici della piattaforma vengono aggiunti direttamente al progetto specifico della piattaforma.
  • stringhe: Questa directory contiene stringhe e risorse per la localizzazione dell'applicazione. Il stringhe la directory contiene directory separate per ogni lingua supportata. Il it-IT la directory, ad esempio, contiene risorse per la lingua inglese (USA).
  • Modelli: Nel pattern MVVM, il modello racchiude la logica e i dati aziendali. In generale, il modello implementa le funzionalità che semplificano il collegamento delle proprietà al livello di vista. Ciò significa che supporta le notifiche "property changed" e "collection changed" attraverso il INotifyPropertyChanged e INotifyCollectionChanged interfacce.
  • ViewModels: Il modello di visualizzazione nel modello MVVM incapsula la logica di presentazione e i dati per la vista. Non ha alcun riferimento diretto alla vista o alcuna conoscenza sull'implementazione o sul tipo di visualizzazione.
  • Convertitori: Questa directory contiene i convertitori di valori. Un convertitore di valori è un modo conveniente per convertire i dati da un tipo all'altro. Implementa il IValueConverter interfaccia.
  • Temi: Il Temi la directory contiene risorse tematiche di tipo ResourceDictionary. Le risorse specifiche della piattaforma vengono aggiunte direttamente al progetto specifico e le risorse condivise vengono aggiunte al progetto condiviso.
  • Servizi: Questa sezione può includere classi per chiamate di servizi Web, servizi di navigazione, ecc.
  • utils include funzioni di utilità che possono essere utilizzate in tutta l'app. Esempi inclusi AppCachefileutilscostantiNetworkAvailabilityGeoLocation, eccetera.
  • Visualizzazioni: Questa directory contiene i layout dell'interfaccia utente. Le viste specifiche della piattaforma vengono aggiunte direttamente al progetto specifico della piattaforma e le viste comuni vengono aggiunte al progetto condiviso.

A seconda del tipo di visualizzazione, il nome dovrebbe terminare con:

  • Finestra, una finestra non modale
  • Dialogo, una finestra di dialogo (modale)
  • Pagina, una visualizzazione di pagina (utilizzata principalmente nelle app Windows Phone e Windows Store)
  • vista, una vista che viene utilizzata come sottoview in un'altra vista, pagina, finestra o finestra di dialogo

Il nome di un modello di vista è composto dal nome della vista corrispondente e dalla parola "Modello". I modelli di visualizzazione sono memorizzati nella stessa posizione nel ViewModels directory come le loro viste corrispondenti in Visualizzazioni elenco.

4. Aggiunta del livello del modello di vista

Il livello del modello di vista implementa proprietà e comandi a cui la vista può associare dati e notificare la visualizzazione di eventuali cambiamenti di stato attraverso eventi di notifica delle modifiche. Le proprietà e i comandi forniti dal modello di visualizzazione definiscono la funzionalità offerta dall'interfaccia utente. Il seguente elenco riepiloga le caratteristiche, i compiti e le responsabilità del livello del modello di vista:

  • Coordina l'interazione della vista con qualsiasi classe del modello.
  • Il modello di vista e le classi del modello generalmente hanno una relazione uno-a-molti.
  • Può convertire o manipolare i dati del modello in modo che possa essere facilmente utilizzato dalla vista.
  • Può definire proprietà aggiuntive per supportare in modo specifico la vista.
  • Definisce gli stati logici che la vista può utilizzare per fornire modifiche visive all'interfaccia utente.
  • Definisce i comandi e le azioni che l'utente può attivare.

Nei passaggi successivi, aggiungiamo due file al livello del modello di vista, ViewModelLocator.csMainViewModel.cs.

Passaggio 1: aggiungere il MainViewModel Classe

Innanzitutto, fare clic con il tasto destro del mouse sul progetto condiviso e selezionare Inserisci, Nuova cartella. Assegna un nome alla cartella ViewModels. Quindi, fare clic con il tasto destro del mouse su ViewModels cartella e selezionare Inserisci, Nuovo oggetto aggiungere il MainViewModel classe.

Modifica il MainViewModel classe per assomigliare a questo:

public class MainViewModel: ViewModelBase stringa privata _helloWorld; stringa pubblica HelloWorld get return _helloWorld;  set Set (() => HelloWorld, ref _helloWorld, valore);  public MainViewModel () HelloWorld = IsInDesignMode? "Esegui in modalità progettazione": "Esegui in modalità runtime"; 

La classe contiene una proprietà pubblica Ciao mondo di tipo stringa. È possibile aggiungere ulteriori metodi, proprietà osservabili e comandi al modello di vista.

Passaggio 2: aggiungere il ViewModelLocator Classe

Aggiungeremo una proprietà pubblica per tutti i modelli di visualizzazione in ViewModelLocator classe e creare una nuova risorsa, che useremo nel designer.

Fare clic con il tasto destro del mouse su ViewModels cartella e selezionare Inserisci, Nuovo oggetto. Seleziona una classe e nominala ViewModelLocator.cs. Aggiorna il ViewModelLocator classe come mostrato di seguito.

public class ViewModelLocator public MainViewModel Main get return ServiceLocator.Current.GetInstance();  static ViewModelLocator () ServiceLocator.SetLocatorProvider (() => SimpleIoc.Default); SimpleIoc.Default.Register(); 

Il ViewModelLocator la classe contiene una proprietà pubblica Principale il cui getter restituisce un'istanza del MainViewModel classe. Il costruttore di ViewModelLocator registra il MainViewModel istanza al SimpleIoc servizio.

Avanti, aperto App.xaml file e aggiungere una nuova risorsa con il ViewModelLocator da utilizzare nel designer.

  

5. Cablare il contesto dei dati

La vista e il modello di vista possono essere costruiti e associati in runtime in più modi. L'approccio più semplice è che la vista istanzia il suo modello di visualizzazione corrispondente in XAML. È anche possibile specificare in XAML che il modello di vista sia impostato come contesto dati della vista.

  

Quando il MainPage.xaml pagina è inizializzata, un'istanza di MainViewModel viene automaticamente creato e impostato come contesto dati della vista. Si noti che il modello di visualizzazione deve avere un costruttore parametrico predefinito per far funzionare questo approccio.

Un altro approccio consiste nel creare l'istanza del modello di vista a livello di codice nel costruttore della vista e impostarla come contesto dati.

public MainPage () InitializeComponent (); this.DataContext = new MainViewModel (); 

Un altro approccio consiste nel creare un'istanza del modello di vista e associarla alla sua vista utilizzando un localizzatore del modello di vista. Nell'app di esempio, usiamo il ViewModelLocator classe per risolvere il modello di vista per MainPage.xaml.

  

Ora che il contesto dati della vista è stato impostato su MainViewModel classe, possiamo accedere alle sue proprietà nella vista. È possibile associare il testo di a TextBlock al Ciao mondo proprietà definita nel modello di vista.

6. Servizio Messenger

Il servizio di messaggistica in MVVM Light consente la comunicazione tra i modelli di visualizzazione o tra i modelli di vista e le viste. Supponiamo che tu disponga di un modello di visualizzazione utilizzato per fornire la logica aziendale a una funzione di ricerca e due modelli di visualizzazione sulla pagina che desiderano elaborare la ricerca per mostrare l'output. Il messaggero sarebbe il modo ideale per farlo in modo approssimativo.

Il modello di vista che ottiene i dati di ricerca semplicemente invierà un messaggio di "ricerca" che verrebbe consumato da qualsiasi modello di vista attualmente registrato per consumare il messaggio. I vantaggi dell'utilizzo di un servizio di messaggistica sono:

  • facile comunicazione tra i modelli di vista senza che ogni modello di vista debba conoscersi l'un l'altro
  • più messaggi i consumatori possono essere aggiunti con poco sforzo
  • mantiene i modelli di vista semplici

Per inviare un messaggio:

MessengerInstance.Send (payload, token);

Per ricevere un messaggio:

MessengerInstance.Register(questo, token, payload => SomeAction (payload));

Nell'applicazione di esempio, invieremo un messaggio da MainViewModel, che sarà ricevuto da MainPage.xaml. Questi sono i passaggi necessari per l'utilizzo del servizio di messaggistica.

Passaggio 1: creare una classe per contenere il messaggio da trasmettere

Creare una nuova classe nel progetto e nominarla showMessageDialog.

public class ShowMessageDialog public string Messaggio get; impostato; 

Passaggio 2: Istanziare Classe messaggio e Messaggio broadcast

Nel MainViewModel.cs, creare un'istanza di showMessageDialog e usa il Messaggero oggetto per trasmettere il messaggio.

oggetto privato ShowMessage () var msg = new ShowMessageDialog Message = "Hello World"; Messenger.Default.Send(Msg); return null; 

Questo trasmette il messaggio. Tutto quello che ci resta da fare è registrare un destinatario e rispondere al messaggio.

Passaggio 3: registrazione per messaggio e gestione al momento della ricezione

Aperto MainPage.xaml.cs e registrati per il messaggio nel costruttore.

public MainPage () this.InitializeComponent (); Messenger.Default.Register (this, (action) => ReceiveMessage (action)); 

ReceiveMessage è un metodo che devi implementare. Ci vorrà il Messaggio oggetto e usa il DialogService per visualizzare una finestra di dialogo.

private async void ReceiveMessage (azione ShowMessageDialog) DialogService dialogService = new DialogService (); attende dialogService.ShowMessage (action.Message, "Sample Universal App"); 

Passaggio 4: creare un comando per inviare un messaggio

Ora che possiamo inviare e ricevere un messaggio, dobbiamo chiamare il ShowMessage metodo. MVVM Light fornisce supporto per RelayCommand, che può essere usato per creare comandi nel modello di vista. Aggiungi una proprietà pubblica ShowMessageCommand nel MainViewModel classe che invoca il ShowMessage metodo.

RelayCommand privato _showMessageCommand; public RelayCommand ShowMessageCommand => _showMessageCommand ?? (_showMessageCommand = new RelayCommand (ShowMessage));

Quindi, aggiungere un PulsanteMainPage.xaml e legare il ShowMessageCommand al suo Comando proprietà.

Distribuire l'app per vedere se tutto funziona come previsto. Ecco un'istantanea di come MainPage.xaml guarda su Windows 8.1.

Quando fai clic sul Cliccami pulsante, viene visualizzata una finestra di dialogo.

Messenger è un componente potente che facilita la comunicazione, ma rende anche il codice più difficile da eseguire il debug perché non è sempre chiaro a prima vista quali oggetti stanno ricevendo un messaggio.

Conclusione

Implementando il modello MVVM, abbiamo una netta separazione tra la vista, il modello di vista e i livelli del modello. In genere, proviamo a sviluppare il modello di visualizzazione in modo che non sappia nulla sulla vista che guida. Questo ha molti vantaggi:

  • Il team di sviluppo può lavorare indipendentemente dal team dell'interfaccia utente.
  • Il modello di visualizzazione può essere testato facilmente, semplicemente chiamando alcuni comandi e metodi e affermando il valore delle proprietà.
  • È possibile apportare modifiche alla vista senza doversi preoccupare dell'effetto che avrà sul modello di vista e sul modello.

Sentiti libero di scaricare i file sorgente del tutorial da usare come riferimento.