Silverlight - Visualizza modello

In questo capitolo esamineremo una tecnica importante nello sviluppo del software Silverlight, l'uso di View Models.

  • Il view model è un elemento chiave, che introduce una tecnica chiamata presentazione separata mantenendo la vista separata dal modello.

  • View Models offrono un modo per ottenere una presentazione separata e vedremo come sfruttano il data binding di Silverlight per ridurre la quantità di codice necessaria nell'interfaccia utente.

Sfide nello sviluppo dell'interfaccia utente

View Modelssono progettati per risolvere alcuni problemi che si presentano frequentemente durante lo sviluppo di software dell'interfaccia utente. Forse il più importante è che il codice dell'interfaccia utente è spesso difficile da testare inestricabilmente, specialmente con i test di unità automatizzati. Esistono anche problemi di qualità del codice che possono influenzare la flessibilità e la manutenibilità del codice.

  • Se segui il percorso di minor resistenza che gli strumenti di progettazione di Visual Studio ti portano giù, puoi finire per inserire troppo codice nel codice sottostante.

  • È molto comune vedere grandi quantità di funzionalità dell'applicazione aggiunte al codice sottostante.

  • Pochi sviluppatori pianificherebbero effettivamente di inserire la logica aziendale in una classe dell'interfaccia utente, ma poiché è lì che Visual Studio mette i gestori di eventi, diventa un posto fin troppo conveniente per fare le cose.

  • È ampiamente accettato che il software sia più facile da sviluppare e mantenere se le classi hanno responsabilità ben definite e ragionevolmente limitate.

  • Il compito del codice è interagire direttamente con gli oggetti che compongono l'interfaccia utente dove è necessario.

  • Non appena inizi a inserire il codice che prende le decisioni su come si comporta la tua applicazione, ciò tende a portare a problemi.

  • Non solo la logica dell'applicazione può fluire nel codice che dovrebbe interessare l'interfaccia utente, alcuni sviluppatori iniziano a fare affidamento sui controlli e altri oggetti dell'interfaccia utente per mantenere lo stato dell'applicazione importante.

  • Il modello contiene semplicemente i dati, la vista contiene semplicemente la data formattata e il controller (ViewModel) funge da collegamento tra i due. Il controller potrebbe prendere input dalla vista e posizionarlo sul modello e viceversa.

Presentazione separata

Per evitare i problemi causati dall'inserimento della logica dell'applicazione nel codice sottostante o in XAML, è preferibile utilizzare una tecnica nota come separated presentation. Avendo XAML e codice dietro con il minimo richiesto per lavorare direttamente con gli oggetti dell'interfaccia utente, le classi di un'interfaccia utente contengono anche codice per comportamenti di interazione complessi, logica dell'applicazione e tutto il resto come mostrato di seguito sul lato sinistro.

Caratteristiche importanti della presentazione separata -

  • Con la presentazione separata, la classe dell'interfaccia utente è molto più semplice. Ovviamente ha XAML, ma il codice alla base è poco pratico.

  • La logica dell'applicazione appartiene a una classe separata, spesso denominata model.

  • Molti sviluppatori tentano di usare l'associazione dati per connettere elementi in XAML direttamente alle proprietà nel modello.

  • Il problema è il file model si occupa interamente di ciò che fa l'applicazione e non di come l'utente interagisce con l'applicazione.

  • La maggior parte delle interfacce utente ha uno stato che non appartiene al modello dell'applicazione. Ad esempio, se la tua interfaccia utente utilizza un drag and drop, qualcosa deve tenere traccia di cose come dove si trova l'elemento trascinato in questo momento, come dovrebbe cambiare il suo aspetto mentre si sposta su possibili obiettivi di rilascio e come potrebbero anche questi obiettivi di rilascio cambia quando l'elemento viene trascinato su di essi.

  • Questo tipo di stato può diventare sorprendentemente complesso e deve essere testato a fondo.

  • In pratica, normalmente si desidera che un'altra classe si trovi tra l'interfaccia utente e il modello. Questo ha due ruoli importanti.

    • Innanzitutto, adatta il modello dell'applicazione per una particolare visualizzazione dell'interfaccia utente.

    • In secondo luogo, è dove vive ogni logica di interazione non banale, e con questo intendo il codice richiesto per far sì che la tua interfaccia utente si comporti nel modo desiderato.

Model / View / ViewModel

View Modelè un esempio dell'approccio di presentazione separata, ma cerchiamo di essere chiari su esattamente che tipo di cose abbiamo in ogni livello. Ci sono tre livelli:

  • Model
  • View
  • ViewModel

Modello

Questo è un classic modello a oggetti composto da normali classi C # che non hanno alcuna relazione diretta con l'interfaccia utente.

Normalmente ti aspetteresti che i codici del modello possano essere compilati senza riferimenti a nessuna libreria dell'interfaccia utente. In effetti, probabilmente saresti in grado di prendere lo stesso identico codice sorgente e compilarlo in un'applicazione Silverlight, una normale applicazione console .NET o persino codice Web lato server.

I tipi nel modello dovrebbero rappresentare i concetti con cui funziona l'applicazione.

Visualizza

Una visualizzazione è normalmente un UserControl, potrebbe essere la tua MainPage o potrebbe essere solo una parte della tua pagina.

Nella maggior parte delle applicazioni Silverlight, è una buona idea suddividere l'interfaccia utente in piccoli pezzi definendo un controllo utente o una vista per ogni pezzo.

Le applicazioni Silverlight non sono uniche in questo senso. Qualcosa che è ovviamente specifico di Silverlight è la vista. Più fine è la tua interfaccia utente, migliori saranno le cose. Non solo hai meno probabilità di inciampare su altri sviluppatori che lavorano sugli stessi file, ma mantenere le cose piccole e semplici scoraggia naturalmente le scorciatoie che portano a codice simile a spaghetti.

Ad esempio, è molto comune definire un file View per rappresentare un singolo elemento in un elenco.

ViewModel

Infine, per ciascuno View, scrivi un file ViewModel. Quindi, questa è una delle caratteristiche importanti di aViewModel classe.

Esiste per servire una vista particolare. IlViewModel è specializzato per un modo particolare di presentare le cose, come un particolare elemento di dati come appare negli elenchi.

Questo è il motivo per cui si chiama a ViewModel; adatta il Modello sottostante specialmente per una particolare Vista. Come il modello, ilViewModelè anche una normale classe C #. Non necessita di derivare da nessun tipo particolare.

In effetti, alcuni sviluppatori trovano conveniente inserire alcune funzionalità comuni in una classe ViewModel di base, ma il modello non lo richiede. In particolare, il tuoViewModelnon deriva da alcun tipo specifico di Silverlight. Tuttavia, a differenza del modello, può utilizzare i tipi Silverlight nelle sue proprietà.

Ad esempio, il tuo ViewModel potrebbe scegliere di rendere visibili alcune parti dell'interfaccia utente solo in determinate condizioni, quindi potresti fornire una proprietà di tipo System.Windows.Visibility, che è il tipo utilizzato dagli elementi Silverlight per la loro proprietà Visibility. Ciò rende possibile legare la visibilità di un elemento, come un pannello, direttamente al ViewModel.

Esempio

Vediamo un semplice esempio in cui useremo Model-View-ViewModel (MVVM) approccio.

Step 1 - Crea un nuovo progetto applicazione Silverlight SilverlightMVVMDemo.

Step 2 - Aggiungi le tre cartelle (Model, ViewModel e Views) al tuo progetto come mostrato di seguito.

Step 3 - Aggiungi una classe StudentModel nella cartella Model e incolla il codice seguente in quella classe.

using System.ComponentModel; 
 
namespace SilverlightMVVMDemo.Model { 

   public class StudentModel {} 
	
   public class Student : INotifyPropertyChanged { 
      private string firstName; 
      private string lastName;  
		
      public string FirstName { 
         get { return firstName; } 
			
         set {
            if (firstName != value) { 
               firstName = value; 
               RaisePropertyChanged("FirstName"); 
               RaisePropertyChanged("FullName"); 
            } 
         } 
      }
		
      public string LastName { 
         get { return lastName; } 
			
         set { 
            if (lastName != value) { 
               lastName = value; 
               RaisePropertyChanged("LastName"); 
               RaisePropertyChanged("FullName"); 
            } 
         } 
      }  
		
      public string FullName { 
         get { 
            return firstName + " " + lastName; 
         } 
      } 
		
      public event PropertyChangedEventHandler PropertyChanged; 
		
      private void RaisePropertyChanged(string property) { 
         if (PropertyChanged != null) { 
            PropertyChanged(this, new PropertyChangedEventArgs(property)); 
         } 
      } 
   } 
}

Step 4 - Aggiungi un'altra classe StudentViewModel nella cartella ViewModel e incolla il codice seguente.

using SilverlightMVVMDemo.Model; 
using System.Collections.ObjectModel;
  
namespace SilverlightMVVMDemo.ViewModel { 

   public class StudentViewModel { 
	
      public ObservableCollection<Student> Students {  
         get;  
         set;  
      }  
		
      public void LoadStudents() { 
         ObservableCollection<Student> students = new ObservableCollection<Student>(); 
				
         students.Add(new Student { FirstName = "Mark", LastName = "Allain" }); 
         students.Add(new Student { FirstName = "Allen", LastName = "Brown" }); 
         students.Add(new Student { FirstName = "Linda", LastName = "Hamerski" });
			
         Students = students; 
      } 
   } 
}

Step 5 - Aggiungi Silverlight User Control facendo clic con il pulsante destro del mouse su Views cartella e seleziona Add New Item….

Step 6- Fare clic su Aggiungi. Ora vedrai il file XAML. Aggiungi il codice seguente inStudentView.xaml file, che contiene diversi elementi dell'interfaccia utente.

<UserControl x:Class = "SilverlightMVVMDemo.Views.StudentView" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White">
	
      <StackPanel HorizontalAlignment = "Left">
		
         <ItemsControl ItemsSource = "{Binding Path=Students}">
			
            <ItemsControl.ItemTemplate>
				
               <DataTemplate> 
					
                  <StackPanel Orientation = "Horizontal"> 
                     <TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}" 
                        Width = "100" Margin = "3 5 3 5"/> 
								
                     <TextBox Text = "{Binding Path = LastName, Mode = TwoWay}"  
                        Width = "100" Margin = "0 5 3 5"/> 
								
                     <TextBlock  Text = "{Binding Path = FullName, Mode=OneWay}" 
                        Margin = "0 5 3 5"/> 
								
                  </StackPanel>
						
               </DataTemplate> 
					
            </ItemsControl.ItemTemplate>
				
         </ItemsControl> 
			
      </StackPanel> 
		
   </Grid> 
	
</UserControl>

Step 7 - Ora aggiungi il file StudentView nel tuo MainPage.xaml file come mostrato di seguito.

<UserControl x:Class = "SilverlightMVVMDemo.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:views = "clr-namespace:SilverlightMVVMDemo.Views" 
   mc:Ignorable = "d" 
   d:DesignHeight = "576.316" d:DesignWidth = "863.158"> 
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <views:StudentView x:Name = "StudentViewControl" Loaded = "StudentViewControl_Loaded"/> 
   </Grid> 
	
</UserControl>

Step 8 - Ecco l'implementazione di Loaded evento nel MainPage.xaml.cs file, che aggiornerà il file View dal ViewModel.

using System.Windows; 
using System.Windows.Controls; 
 
namespace SilverlightMVVMDemo { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent();
      }
   } 
	
   private void StudentViewControl_Loaded(object sender, RoutedEventArgs e) { 
      SilverlightMVVMDemo.ViewModel.StudentViewModel 
      studentViewModelObject = new SilverlightMVVMDemo.ViewModel.
      StudentViewModel(); 
      studentViewModelObject.LoadStudents();  
      StudentViewControl.DataContext = studentViewModelObject;  
   } 
}

Step 9 - Quando il codice sopra è stato compilato ed eseguito, vedrai il seguente output sulla tua pagina web.

UI vs ViewModel

Una delle parti più difficili dell'approccio MVVM è capire dove dovrebbe arrivare la linea di demarcazione. Non è sempre ovvio quali cose appartengano a dove.

  • In particolare, alcuni elementi dell'interfaccia utente forniscono funzionalità che, secondo una visualizzazione rigorosa, dovrebbero probabilmente appartenere al ViewModel.

  • In generale, non tutti i comportamenti implementati in View sono così ViewModel amichevole.

  • Parte del motivo è che non esiste un modo standard per impacchettare il comportamento di ViewModel per il riutilizzo, in particolare non se si desidera utilizzare un ambiente di progettazione, come Visual Studio o Blend.

Vantaggi di MVVM

MVVM offre i seguenti vantaggi:

  • Separazione dei problemi di presentazione (View, ViewModel, Model)

  • Codice pulito, verificabile e gestibile. Può includere la logica del livello di presentazione nei test di unità.

  • Nessun codice dietro il codice, quindi il livello di presentazione e la logica sono vagamente accoppiati.

  • Modo migliore per legare i dati.

Svantaggi di MVVM

Per semplici interfacce utente, MVVM può essere eccessivo. Il debug sarebbe un po 'difficile quando abbiamo associazioni di dati complesse.