MVVM - Modèles de données WPF

Un modèle décrit l'aspect général et l'aspect visuel du contrôle. Pour chaque contrôle, un modèle par défaut lui est associé qui donne l'apparence à ce contrôle. Dans l'application WPF, vous pouvez facilement créer vos propres modèles lorsque vous souhaitez personnaliser le comportement visuel et l'apparence visuelle d'un contrôle. La connectivité entre la logique et le modèle peut être obtenue par liaison de données.

Dans MVVM, il existe une autre forme principale connue sous le nom de première construction ViewModel.

  • La première approche de construction de ViewModel exploite les capacités des modèles de données implicites dans WPF.

  • Les modèles de données implicites peuvent sélectionner automatiquement un modèle approprié dans le dictionnaire de ressources actuel pour un élément qui utilise la liaison de données. Ils le font en fonction du type d'objet de données rendu par la liaison de données. Tout d'abord, vous devez disposer d'un élément lié à un objet de données.

Jetons à nouveau un coup d'œil à notre exemple simple dans lequel vous comprendrez comment vous pouvez d'abord afficher le modèle en exploitant les modèles de données, en particulier les modèles de données implicites. Voici l'implémentation de notre classe StudentViewModel.

using MVVMDemo.Model; 
using System.Collections.ObjectModel;

namespace MVVMDemo.ViewModel { 

   public class StudentViewModel {
	
      public StudentViewModel() { 
         LoadStudents(); 
      } 
		
      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; 
      } 
   } 
}

Vous pouvez voir que le ViewModel ci-dessus est inchangé. Nous continuerons avec le même exemple du chapitre précédent. Cette classe ViewModel expose simplement la propriété de collection Students et la remplit lors de la construction. Allons au fichier StudentView.xaml, supprimons l'implémentation existante et définissons un modèle de données dans la section Ressources.

<UserControl.Resources> 
   <DataTemplate x:Key = "studentsTemplate">
	
      <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> 
</UserControl.Resources>

Ajoutez maintenant une zone de liste et les données lient cette zone de liste à la propriété des étudiants, comme indiqué dans le code suivant.

<ListBox ItemsSource = "{Binding Students}" ItemTemplate = "{StaticResource studentsTemplate}"/>

Dans la section Ressource, le DataTemplate a une clé de StudentsTemplate, puis pour utiliser réellement ce modèle, nous devons utiliser la propriété ItemTemplate d'un ListBox. Vous pouvez maintenant voir que nous demandons à la zone de liste d'utiliser ce modèle spécifique pour rendre ces étudiants. Voici l'implémentation complète du fichier StudentView.xaml.

<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.Resources> 
      <DataTemplate x:Key = "studentsTemplate"> 
		
         <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> 
   </UserControl.Resources>
	
   <Grid> 
      <ListBox 
         ItemsSource = "{Binding Students}" 
         ItemTemplate = "{StaticResource studentsTemplate}"/> 
   </Grid>
	
</UserControl>

Lorsque le code ci-dessus est compilé et exécuté, vous verrez la fenêtre suivante, qui contient une ListBox. Chaque ListBoxItem contient les données d'objet de classe Student qui sont affichées dans les zones TextBlock et Text.

Pour en faire un modèle implicite, nous devons supprimer la propriété ItemTemplate d'une zone de liste et ajouter une propriété DataType dans notre définition de modèle, comme indiqué dans le code suivant.

<UserControl.Resources> 
   <DataTemplate DataType = "{x:Type data:Student}">
	
      <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> 
</UserControl.Resources>
 
<Grid> 
   <ListBox ItemsSource = "{Binding Students}"/> 
</Grid>

Dans DataTemplate, l'extension de balisage x: Type est très importante et ressemble à un type d'opérateur en XAML. Donc, fondamentalement, nous devons pointer vers le type de données Student qui se trouve dans l'espace de noms MVVMDemo.Model. Voici le fichier XAML complet mis à jour.

<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:data = "clr-namespace:MVVMDemo.Model" 
   xmlns:vml = "clr-namespace:MVVMDemo.VML" 
   vml:ViewModelLocator.AutoHookedUpViewModel = "True" 
   mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300">
	
   <UserControl.Resources> 
      <DataTemplate DataType = "{x:Type data:Student}"> 
		
         <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> 
   </UserControl.Resources>
	
   <Grid>
      <ListBox ItemsSource = "{Binding Students}"/> 
   </Grid> 
	
</UserControl>

Lorsque vous exécutez à nouveau cette application, vous obtiendrez toujours le même rendu du modèle Etudiants avec données, car il mappe automatiquement le type de l'objet rendu en localisant le DataTemplate approprié.

Nous vous recommandons d'exécuter l'exemple ci-dessus dans une méthode étape par étape pour une meilleure compréhension.