MVVM: enlaces de datos de WPF

En este capítulo, aprenderemos cómo el enlace de datos admite el patrón MVVM. El enlace de datos es la característica clave que diferencia MVVM de otros patrones de separación de UI como MVC y MVP.

  • Para el enlace de datos, necesita tener una vista o un conjunto de elementos de la interfaz de usuario construidos, y luego necesita algún otro objeto al que apunten los enlaces.

  • Los elementos de la interfaz de usuario de una vista están vinculados a las propiedades expuestas por ViewModel.

  • El orden en el que se construyen la Vista y el Modelo de Vista depende de la situación, ya que hemos cubierto la Vista primero.

  • Se construyen una vista y un modelo de vista y el DataContext de la vista se establece en ViewModel.

  • Los enlaces pueden ser enlaces de datos OneWay o TwoWay para hacer fluir datos de un lado a otro entre View y ViewModel.

Echemos un vistazo a los enlaces de datos en el mismo ejemplo. A continuación se muestra el código XAML de 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>
  • Si observa el código XAML anterior, verá que ItemsControl está vinculado a la colección Students expuesta por ViewModel.

  • También puede ver que la propiedad del modelo Student también tiene sus propios enlaces individuales, y estos están enlazados a Textboxes y TextBlock.

  • ItemSource de ItemsControl se puede enlazar a la propiedad Students, porque el DataContext general para la vista está establecido en ViewModel.

  • Los enlaces individuales de las propiedades aquí también son enlaces DataContext, pero no están vinculados al ViewModel en sí, debido a la forma en que funciona un ItemSource.

  • Cuando la fuente de un elemento se une a su colección, representa un contenedor para cada elemento en la representación y establece el DataContext de ese contenedor en el elemento. Entonces, el DataContext general para cada cuadro de texto y bloque de texto dentro de una fila será un Estudiante individual en la colección. Y también puede ver que estos enlaces para TextBoxes son enlaces de datos TwoWay y para TextBlock es un enlace de datos OneWay, ya que no puede editar TextBlock.

Cuando vuelva a ejecutar esta aplicación, verá el siguiente resultado.

Ahora cambiemos el texto en el segundo cuadro de texto de la primera fila de Allain a Upston y presione tabulador para perder el enfoque. Verá que el texto TextBlock también se actualiza.

Esto se debe a que los enlaces de los TextBoxes se establecen en TwoWay y también actualiza el Modelo, y desde el modelo nuevamente se actualiza el TextBlock.