MVVM - WPF-Datenvorlagen
Eine Vorlage beschreibt das allgemeine Erscheinungsbild und das visuelle Erscheinungsbild des Steuerelements. Jedem Steuerelement ist eine Standardvorlage zugeordnet, die diesem Steuerelement das Erscheinungsbild verleiht. In der WPF-Anwendung können Sie ganz einfach Ihre eigenen Vorlagen erstellen, wenn Sie das visuelle Verhalten und das visuelle Erscheinungsbild eines Steuerelements anpassen möchten. Die Konnektivität zwischen Logik und Vorlage kann durch Datenbindung erreicht werden.
In MVVM gibt es eine andere primäre Form, die als ViewModel-Erstkonstruktion bezeichnet wird.
Der erste Konstruktionsansatz von ViewModel nutzt die Funktionen impliziter Datenvorlagen in WPF.
Implizite Datenvorlagen können automatisch eine geeignete Vorlage aus dem aktuellen Ressourcenwörterbuch für ein Element auswählen, das Datenbindung verwendet. Sie tun dies basierend auf dem Typ des Datenobjekts, das durch Datenbindung gerendert wird. Zunächst benötigen Sie ein Element, das an ein Datenobjekt gebunden ist.
Schauen wir uns noch einmal unser einfaches Beispiel an, in dem Sie verstehen, wie Sie das Modell zuerst mithilfe von Datenvorlagen, insbesondere impliziten Datenvorlagen, anzeigen können. Hier ist die Implementierung unserer StudentViewModel-Klasse.
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;
}
}
}
Sie können sehen, dass das obige ViewModel unverändert ist. Wir werden mit demselben Beispiel aus dem vorherigen Kapitel fortfahren. Diese ViewModel-Klasse macht nur die Students-Auflistungseigenschaft verfügbar und füllt sie bei der Erstellung. Gehen wir zur Datei StudentView.xaml, entfernen die vorhandene Implementierung und definieren eine Datenvorlage im Abschnitt Ressourcen.
<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>
Fügen Sie nun ein Listenfeld hinzu, und Daten binden dieses Listenfeld an die Students-Eigenschaft, wie im folgenden Code gezeigt.
<ListBox ItemsSource = "{Binding Students}" ItemTemplate = "{StaticResource studentsTemplate}"/>
Im Abschnitt "Ressource" verfügt die DataTemplate über den Schlüssel "studentsTemplate". Um diese Vorlage tatsächlich zu verwenden, müssen Sie die ItemTemplate-Eigenschaft einer ListBox verwenden. Jetzt können Sie sehen, dass wir die Listbox anweisen, diese spezielle Vorlage zum Rendern dieser Schüler zu verwenden. Im Folgenden finden Sie die vollständige Implementierung der Datei 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>
Wenn der obige Code kompiliert und ausgeführt wird, wird das folgende Fenster angezeigt, das eine ListBox enthält. Jedes ListBoxItem enthält die Objektobjektdaten der Schülerklasse, die in TextBlock- und Textfeldern angezeigt werden.
Um dies zu einer impliziten Vorlage zu machen, müssen wir die ItemTemplate-Eigenschaft aus einem Listenfeld entfernen und eine DataType-Eigenschaft in unsere Vorlagendefinition einfügen, wie im folgenden Code gezeigt.
<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>
In DataTemplate ist die Markup-Erweiterung x: Type sehr wichtig, die einem Operatortyp in XAML ähnelt. Grundsätzlich müssen wir also auf den Student-Datentyp verweisen, der sich im MVVMDemo.Model-Namespace befindet. Es folgt die aktualisierte vollständige XAML-Datei.
<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>
Wenn Sie diese Anwendung erneut ausführen, erhalten Sie immer noch das gleiche Rendering der Schüler mit Datenvorlage, da der Typ des gerenderten Objekts automatisch durch Suchen der entsprechenden DataTemplate zugeordnet wird.
Wir empfehlen Ihnen, das obige Beispiel zum besseren Verständnis Schritt für Schritt auszuführen.