MVVM - Associazioni dati WPF

In questo capitolo impareremo come il data binding supporta il pattern MVVM. Il data binding è la caratteristica chiave che differenzia MVVM da altri modelli di separazione dell'interfaccia utente come MVC e MVP.

  • Per l'associazione dati è necessario disporre di una vista o di un set di elementi dell'interfaccia utente costruiti, quindi è necessario un altro oggetto a cui punteranno le associazioni.

  • Gli elementi dell'interfaccia utente in una visualizzazione sono associati alle proprietà esposte da ViewModel.

  • L'ordine in cui sono costruiti View e ViewModel dipende dalla situazione, poiché abbiamo trattato prima la View.

  • Vengono creati View e ViewModel e il DataContext della View viene impostato su ViewModel.

  • Le associazioni possono essere associazioni di dati OneWay o TwoWay per far scorrere i dati avanti e indietro tra View e ViewModel.

Diamo uno sguardo alle associazioni di dati nello stesso esempio. Di seguito è riportato il codice XAML di StudentView.

<UserControl x:Class = "MVVMDemo.Views.StudentView" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:local = "clr-namespace:MVVMDemo.Views" 
   xmlns:viewModel = "clr-namespace:MVVMDemo.ViewModel" 
   xmlns:vml = "clr-namespace:MVVMDemo.VML" 
   vml:ViewModelLocator.AutoHookedUpViewModel = "True" 
   mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300">

   <!--<UserControl.DataContext> 
      <viewModel:StudentViewModel/> 
   </UserControl.DataContext>--> 

   <Grid> 
      <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>
  • Se guardi il codice XAML sopra, vedrai che ItemsControl è associato alla raccolta Students esposta da ViewModel.

  • Puoi anche vedere che la proprietà del modello Student ha anche le proprie associazioni individuali e queste sono associate alle Textboxes e TextBlock.

  • ItemSource di ItemsControl è in grado di eseguire il binding alla proprietà Students, perché il DataContext complessivo per la visualizzazione è impostato su ViewModel.

  • Le singole associazioni delle proprietà qui sono anche associazioni DataContext, ma non sono vincolanti al ViewModel stesso, a causa del modo in cui funziona un ItemSource.

  • Quando un'origine dell'elemento si associa alla sua raccolta, esegue il rendering di un contenitore per ogni elemento al momento del rendering e imposta il DataContext di tale contenitore sull'elemento. Quindi il DataContext complessivo per ogni casella di testo e blocco di testo all'interno di una riga sarà un singolo Studente nella raccolta. E puoi anche vedere che queste associazioni per TextBoxes sono l'associazione dati TwoWay e per TextBlock è l'associazione dati OneWay poiché non puoi modificare TextBlock.

Quando esegui di nuovo questa applicazione, vedrai il seguente output.

Cambiamo ora il testo nella seconda casella di testo della prima riga da Allain a Upston e premiamo tab per perdere il focus. Vedrai che anche il testo TextBlock viene aggiornato.

Questo perché le associazioni dei TextBox sono impostate su TwoWay e aggiorna anche il Modello, e dal modello viene nuovamente aggiornato il TextBlock.