Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

MVVM e DataBinding

Come viene implementato il pattern Model-View-ViewModel, definito da Microsoft, all'interno del framework Xamarin per creare app mobile multipiattaforma.
Come viene implementato il pattern Model-View-ViewModel, definito da Microsoft, all'interno del framework Xamarin per creare app mobile multipiattaforma.
Link copiato negli appunti

Nello sviluppo di un’app, è fondamentale strutturare opportunamente il codice per distinguere in modo netto i vari strati ed il relativo comportamento, specie con applicazioni dotate di interfaccia grafica. In tal caso, è fondamentale che l’interfaccia (o UI) sia ben separata dalla logica di business, affinché una modifica nella logica o nel modello di dominio non si rifletta sull’interfaccia.

A tal proposito, un pattern architetturale noto è Model View Controller (MVC), che separa il modello dall’interfaccia attraverso l’impiego di un controller. Da questo pattern sono stati poi derivati ulteriori "dialetti", tra cui Model-View-ViewModel (MVVM), oggetto di questa lezione.

MVVM è un pattern definito da Microsoft per lo sviluppo di applicazioni WPF, Windows Phone e Silverlight basate proprio sullo XAML, ed è stato quindi ripreso da Xamarin proprio per i suoi molteplici benefici. Tra questi, citiamo:

  • la possibilità di creare test per il ViewModel e il Model senza usare la View;
  • la possibilità di ridisegnare la UI dell’app senza dover apportare cambiamenti agli altri due layer;
  • il ViewModel svolge la funzione di adapter per le classi del Model, per evitare di effettuare cambiamenti importanti al codice del Model.

MVVM

Come il nome stesso lascia intendere, MVVM suddivide l’applicazione in tre livelli (o layer):

Model è il punto di accesso ai dati ed è costituito da un insieme di classi che modellano la realtà di interesse e permettono di gestire i dati impiegati nell’app. In Xamarin, è tipicamente una pagina dell’app
View è lo strato di presentazione dell’app, ossia la sua interfaccia grafica, e permette all’utente di interagire con i dati
ViewModel connette la View e il Model e permette di gestire i dati provenienti dal Model per mostrarli nella View una volta elaborati, e viceversa

La modalità di comunicazione tra questi strati si può, quindi, riassumere secondo lo schema della figura seguente.

Figura 54. (click per ingrandire)


L’utente interagisce con la UI, che raccoglie gli input ricevuti e li inoltra al ViewModel. Quest’ultimo, sulla base dell’input ricevuto, effettua un cambio di stato accedendo, quando necessario, al Model. Inoltre, il ViewModel aggiorna il proprio stato affinché si rifletta sulla View. In questo modo, il ViewModel non solo disaccoppia View e Model ma mantiene anche nel suo stato corrente sia le informazioni del Model che della View.

Un aspetto fondamentale per poter applicare correttamente MVVM è che la classe ViewModel non abbia alcun riferimento a Xamarin.Forms e, quindi, ai suoi elementi tipici della View. Nonostante ciò, molteplici esempi della documentazione ufficiale violano questa regola a causa della bassa complessità delle app di esempio proposte. In questa lezione, rispetteremo questa esigenza ma, nonostante ciò, non avremo un Model a disposizione a cui legare i dati ricevuti attraverso la view.

Implementazione

Scopo di questa esercitazione è la creazione di una form composta da tre campi (Name, Nickname, e-mail) inseriti dall’utente e automaticamente mostrati a quest’ultimo in tempo reale.

Figura 55. (click per ingrandire)


Creiamo una nuova Forms Xaml Page chiamandola MVVMDataBinding. Lavoriamo ora sul codice XMAL inserendo tutti gli elementi di interesse rappresentati nel nostro schema, effettuando l’opportunamente il binding tra le risorse come segue in questo esempio.

<Label HorizontalOptions="Start" Text="Name"/>
		<Entry Text="{Binding Name, Mode=TwoWay}" /> 
	<!-- altro codice -->
	<StackLayout Padding="10" Orientation="Horizontal">
	  <Label Text="Your name is:" />
	  <Label Text="{Binding Name}" />
	</StackLayout>

È possibile notare una piccola modifica, ossia la presenza del campo Mode, nel binding proposto con le proprietà che saranno impiegate nel ViewModel. Il markup Binding permette di specificare diverse proprietà tra cui Mode. Questa proprietà è usata per specificare la direzione in cui le modifiche dei valori delle proprietà si propagano nell'app:

OneWay Propagazione dei cambiamenti da un oggetto sorgente a un elemento target della UI (usata di default, non è necessario specificarla)
TwoWay Propagazione dei cambiamenti bidirezionale
OneWayToSource Propagazione dei cambiamenti dall’elemento target all’oggetto sorgente

Definiamo adesso la classe FormViewModel aggiungendo al progetto portable una nuova classe. Per poter applicare MVVM è necessario che la classe implementi l’interfaccia INotifyPropertyChanged, che definisce l’evento PropertyChanged di tipo PropertyChangedEventHandler. Questo evento prende un’istanza della classe PropertyChangedEventArgs che definisce la proprietà PropertyName di tipo string, attraverso la quale è possibile sapere quale proprietà nel ViewModel è cambiata (permettendo all’evento di accedere a quella proprietà). Di seguito, vediamo la definizione dell’evento e del metodo OnPropertyChanged impiegato per l’aggiornamento di stato.

public event PropertyChangedEventHandler PropertyChanged;
	protected virtual void OnPropertyChanged(string propertyName)
	{
		var handler = PropertyChanged;
		if (handler!= null)
		{
			PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
		}
	}

Fatto ciò, è possibile aggiungere alla nostra classe le proprietà che devono essere legate agli elementi della View. Ad esempio, definiamo la proprietà Name:

string name;
	public string Name
	{
		get { return name; }
		set
		{
			if (name != value)
			{
				name = value;
				OnPropertyChanged("Name");
			}
		}
	}

Attraverso la proprietà pubblica Name, offriamo la possibilità lato codice di ottenere le informazioni sul nome corrente attraverso il get, e di impostare un nuovo valore per tale proprietà attraverso il set ogni qualvolta il valore assunto dalla variabile name differisce da quella corrente. Proprio in quest’ultima porzione viene richiamato il metodo OnPropertyChanged, che prenderà in ingresso il nome della proprietà che deve essere aggiornata innescando il meccanismo sopra descritto.

Non resta a questo punto che legare la View con il ViewModel. Si potrebbe fare per ogni singolo componente, ma è possibile ottimizzare questo processo usando la proprietà BindingContex. Aggiungiamo al costruttore presente nel code-behind la seguente riga:

BindingContext = new FormViewModel();

In questo modo, tutti gli elementi della UI hanno lo stesso BindingContex. Un’alternativa è effettuare il binding tramite XAML. A tal proposito, si rimanda a questo approfondimento specifico.

Il codice completo di questa lezione è reperibile ai seguenti link:

Eseguiamo l’applicazione sulle piattaforme di interesse ottenendo il risultato mostrato in Figura 56.

Figura 56. (click per ingrandire)


Ti consigliamo anche