MVVM - Connexions de vues
Dans ce chapitre, nous aborderons différentes manières dont vous pouvez connecter vos vues à ViewModel. Tout d'abord, examinons la première construction de View où nous pouvons la déclarer en XAML. Comme nous l'avons vu l'exemple dans le dernier chapitre où nous avons accroché une vue de la fenêtre principale. Nous allons maintenant voir d'autres façons de connecter des vues.
Nous utiliserons également le même exemple dans ce chapitre. Voici la même implémentation de classe Model.
using System.ComponentModel;
namespace MVVMDemo.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));
}
}
}
}
Voici l'implémentation de la classe ViewModel. Cette fois, la méthode LoadStudents est appelée dans le constructeur par défaut.
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;
}
}
}
Que la vue soit une fenêtre, un contrôle utilisateur ou une page, l'analyseur fonctionne généralement de haut en bas et de gauche à droite. Il appelle le constructeur par défaut pour chaque élément lorsqu'il le rencontre. Il existe deux manières de construire une vue. Vous pouvez en utiliser n'importe lequel.
- Afficher la première construction en XAML
- Voir la première construction dans Code-behind
Afficher la première construction en XAML
Une façon consiste simplement à ajouter votre ViewModel en tant qu'élément imbriqué dans le setter pour la propriété DataContext, comme indiqué dans le code suivant.
<UserControl.DataContext>
<viewModel:StudentViewModel/>
</UserControl.DataContext>
Voici le fichier View XAML complet.
<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"
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>
Voir la première construction dans Code-behind
Une autre façon est que vous pouvez obtenir la première construction de View en construisant simplement le modèle de vue vous-même dans le code derrière votre View en définissant la propriété DataContext avec l'instance.
En règle générale, la propriété DataContext est définie dans la méthode de vue du constructeur, mais vous pouvez également différer la construction jusqu'à ce que l'événement Load de la vue se déclenche.
using System.Windows.Controls;
namespace MVVMDemo.Views {
/// <summary>
/// Interaction logic for StudentView.xaml
/// </summary>
public partial class StudentView : UserControl {
public StudentView() {
InitializeComponent();
this.DataContext = new MVVMDemo.ViewModel.StudentViewModel();
}
}
}
L'une des raisons de la construction du modèle de vue dans Code-behind au lieu de XAML est que le constructeur de modèle View prend des paramètres, mais l'analyse XAML ne peut construire des éléments que s'ils sont définis dans le constructeur par défaut.
Maintenant, dans ce cas, le fichier XAML de View ressemblera à celui indiqué dans le code suivant.
<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"
mc:Ignorable = "d"
d:DesignHeight = "300"
d:DesignWidth = "300">
<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>
Vous pouvez déclarer cette vue dans MainWindow comme indiqué dans le fichier MainWindow.XAML.
<Window x:Class = "MVVMDemo.MainWindow"
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:local = "clr-namespace:MVVMDemo"
xmlns:views = "clr-namespace:MVVMDemo.Views"
mc:Ignorable = "d"
Title = "MainWindow" Height = "350" Width = "525">
<Grid>
<views:StudentView x:Name = "StudentViewControl"/>
</Grid>
</Window>
Lorsque le code ci-dessus est compilé et exécuté, vous verrez la sortie suivante sur votre fenêtre principale.
Nous vous recommandons d'exécuter l'exemple ci-dessus étape par étape pour une meilleure compréhension.