Silverlight - Modell anzeigen
In diesem Kapitel werden wir uns mit einer wichtigen Technik in der Softwareentwicklung von Silverlight befassen, der Verwendung von View Models.
Das view model ist ein Schlüsselstück, das eine Technik einführt, die als getrennte Präsentation bezeichnet wird, indem die Ansicht vom Modell getrennt bleibt.
View Models bieten eine Möglichkeit, eine getrennte Präsentation zu erreichen, und wir werden sehen, wie sie die Datenbindung von Silverlight nutzen, um die Menge an Code zu reduzieren, die in Ihrer Benutzeroberfläche benötigt wird.
Herausforderungen bei der UI-Entwicklung
View Modelswurden entwickelt, um bestimmte Probleme zu lösen, die bei der Entwicklung von Benutzeroberflächensoftware häufig auftreten. Das vielleicht wichtigste ist, dass der Code der Benutzeroberfläche oft schwer untrennbar zu testen ist, insbesondere bei automatisierten Komponententests. Es gibt auch Probleme mit der Codequalität, die sich auf die fortlaufende Flexibilität und Wartbarkeit Ihres Codes auswirken können.
Wenn Sie dem Weg des geringsten Widerstands folgen, den die Designtools von Visual Studio Sie führen, können Sie am Ende viel zu viel Code in den Code dahinter einfügen.
Es kommt sehr häufig vor, dass dem Code dahinter große Mengen an Anwendungsfunktionen hinzugefügt werden.
Nur wenige Entwickler würden tatsächlich planen, Geschäftslogik in eine Benutzeroberflächenklasse zu integrieren. Da Visual Studio hier jedoch Ihre Ereignishandler platziert, ist dies ein allzu praktischer Ort, um die Dinge zu erledigen.
Es ist allgemein anerkannt, dass Software einfacher zu entwickeln und zu warten ist, wenn Klassen klar definierte und einigermaßen enge Verantwortlichkeiten haben.
Der Code hinter der Aufgabe besteht darin, direkt mit den Objekten zu interagieren, aus denen die Benutzeroberfläche besteht, wo dies erforderlich ist.
Sobald Sie anfangen, Code einzufügen, der Entscheidungen darüber trifft, wie sich Ihre Anwendung dort verhält, was zu Problemen führen kann.
Anwendungslogik kann nicht nur in Code fließen, der sich mit der Benutzeroberfläche befassen soll, einige Entwickler verlassen sich auch auf Steuerelemente und andere Benutzeroberflächenobjekte, um wichtige Anwendungsstatus zu speichern.
Das Modell enthält lediglich die Daten, die Ansicht enthält lediglich das formatierte Datum und der Controller (ViewModel) fungiert als Verbindung zwischen beiden. Der Controller nimmt möglicherweise Eingaben aus der Ansicht entgegen und platziert sie auf dem Modell und umgekehrt.
Getrennte Präsentation
Um die Probleme zu vermeiden, die durch das Einfügen von Anwendungslogik in den Code hinter oder XAML verursacht werden, ist es am besten, eine Technik zu verwenden, die als bekannt ist separated presentation. Eine Benutzeroberflächenklasse enthält XAML und Code mit dem Minimum, das für die direkte Arbeit mit Benutzeroberflächenobjekten erforderlich ist, und enthält außerdem Code für komplexes Interaktionsverhalten, Anwendungslogik und alles andere, wie unten links gezeigt.
Wichtige Merkmale der getrennten Präsentation -
Bei einer getrennten Darstellung ist die Benutzeroberflächenklasse viel einfacher. Es hat natürlich XAML, aber der Code dahinter macht so wenig wie praktisch.
Die Anwendungslogik gehört zu einer separaten Klasse, die häufig als bezeichnet wird model.
Viele Entwickler versuchen, mithilfe der Datenbindung Elemente in der XAML direkt mit Eigenschaften im Modell zu verbinden.
Das Problem ist das model befasst sich ausschließlich mit Fragen der Funktionsweise der Anwendung und nicht mit der Interaktion des Benutzers mit der Anwendung.
Die meisten Benutzeroberflächen haben einen Status, der nicht zum Anwendungsmodell gehört. Wenn Ihre Benutzeroberfläche beispielsweise Drag & Drop verwendet, muss etwas nachverfolgen, z. B. wo sich das zu ziehende Objekt gerade befindet, wie sich sein Erscheinungsbild ändern sollte, wenn es sich über mögliche Drop-Ziele bewegt, und wie diese Drop-Ziele möglicherweise auch Ändern Sie, wenn das Element über sie gezogen wird.
Diese Art von Zustand kann überraschend komplex werden und muss gründlich getestet werden.
In der Praxis möchten Sie normalerweise eine andere Klasse zwischen der Benutzeroberfläche und dem Modell. Dies hat zwei wichtige Rollen.
Zunächst wird Ihr Anwendungsmodell an eine bestimmte Ansicht der Benutzeroberfläche angepasst.
Zweitens lebt hier jede nicht triviale Interaktionslogik, und damit meine ich Code, der erforderlich ist, damit sich Ihre Benutzeroberfläche so verhält, wie Sie es möchten.
Model / View / ViewModel
View Modelist ein Beispiel für den Ansatz der getrennten Präsentation, aber lassen Sie uns klarstellen, was genau wir in jeder Ebene haben. Es gibt drei Schichten -
- Model
- View
- ViewModel
Modell
Das ist ein classic Objektmodell bestehend aus gewöhnlichen C # -Klassen, die keine direkte Beziehung zur Benutzeroberfläche haben.
Normalerweise erwarten Sie, dass Ihre Modellcodes ohne Verweise auf Benutzeroberflächenbibliotheken kompiliert werden können. In der Tat könnten Sie wahrscheinlich genau denselben Quellcode in eine Silverlight-Anwendung, eine normale .NET Console-Anwendung oder sogar einen serverseitigen Webcode kompilieren.
Die Typen im Modell sollten die Konzepte darstellen, mit denen Ihre Anwendung arbeitet.
Aussicht
Eine Ansicht ist normalerweise ein UserControl, es kann sich um Ihre Hauptseite handeln oder nur um einen Teil Ihrer Seite.
In den meisten Silverlight-Anwendungen ist es eine gute Idee, die Benutzeroberfläche in kleine Teile aufzuteilen, die ein UserControl oder eine Ansicht für jedes Teil definieren.
Silverlight-Anwendungen sind in dieser Hinsicht nicht eindeutig. Etwas, das offensichtlich Silverlight-spezifisch ist, ist die Ansicht. Je feiner Ihre Benutzeroberfläche ist, desto besser sind die Dinge. Es ist nicht nur weniger wahrscheinlich, dass Sie über andere Entwickler stolpern, die an denselben Dateien arbeiten. Wenn Sie die Dinge klein und einfach halten, werden die Verknüpfungen, die zu spaghettiartigem Code führen, natürlich entmutigt.
Zum Beispiel ist es sehr üblich, a zu definieren View um ein einzelnes Element in einer Liste darzustellen.
ViewModel
Schließlich für jeden View, du schreibst a ViewModel. Dies ist also eines der wichtigen Merkmale von aViewModel Klasse.
Es existiert, um einer bestimmten Ansicht zu dienen. DasViewModel ist auf eine bestimmte Art der Darstellung von Dingen spezialisiert, z. B. auf ein bestimmtes Datenelement, wie es in Listen angezeigt wird.
Deshalb heißt es a ViewModel;; Es passt das zugrunde liegende Modell speziell für eine bestimmte Ansicht an. Wie das Modell, dasViewModelist auch eine gewöhnliche C # -Klasse. Es muss nicht von einem bestimmten Typ abgeleitet sein.
Einige Entwickler finden es praktisch, einige allgemeine Funktionen in eine ViewModel-Basisklasse zu integrieren, aber das Muster verlangt dies nicht. Insbesondere IhreViewModelleitet sich nicht von einem Silverlight-spezifischen Typ ab. Im Gegensatz zum Modell kann es jedoch Silverlight-Typen in seinen Eigenschaften verwenden.
Beispielsweise kann Ihr ViewModel bestimmte Teile Ihrer Benutzeroberfläche nur unter bestimmten Bedingungen sichtbar machen. Daher können Sie eine Eigenschaft vom Typ System.Windows.Visibility angeben, die der Typ Silverlight-Elemente ist, die für ihre Sichtbarkeitseigenschaft verwendet werden. Auf diese Weise können Sie die Sichtbarkeit eines Elements, z. B. eines Bedienfelds, direkt an das ViewModel binden.
Beispiel
Schauen wir uns ein einfaches Beispiel an, in dem wir verwenden werden Model-View-ViewModel (MVVM) Ansatz.
Step 1 - Erstellen Sie ein neues Silverlight-Anwendungsprojekt SilverlightMVVMDemo.
Step 2 - Fügen Sie die drei Ordner (Model, ViewModel und Views) wie unten gezeigt zu Ihrem Projekt hinzu.
Step 3 - Fügen Sie eine StudentModel-Klasse in den Modellordner ein und fügen Sie den folgenden Code in diese Klasse ein.
using System.ComponentModel;
namespace SilverlightMVVMDemo.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));
}
}
}
}
Step 4 - Fügen Sie eine weitere StudentViewModel-Klasse zum ViewModel-Ordner hinzu und fügen Sie den folgenden Code ein.
using SilverlightMVVMDemo.Model;
using System.Collections.ObjectModel;
namespace SilverlightMVVMDemo.ViewModel {
public class StudentViewModel {
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;
}
}
}
Step 5 - Hinzufügen Silverlight User Control durch Klicken mit der rechten Maustaste auf Views Ordner und Auswählen Add New Item….
Step 6- Klicken Sie auf Hinzufügen. Jetzt sehen Sie die XAML-Datei. Fügen Sie den folgenden Code hinzuStudentView.xaml Datei, die verschiedene UI-Elemente enthält.
<UserControl x:Class = "SilverlightMVVMDemo.Views.StudentView"
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"
mc:Ignorable = "d"
d:DesignHeight = "300" d:DesignWidth = "400">
<Grid x:Name = "LayoutRoot" Background = "White">
<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>
Step 7 - Fügen Sie nun die hinzu StudentView in dein MainPage.xaml Datei wie unten gezeigt.
<UserControl x:Class = "SilverlightMVVMDemo.MainPage"
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:views = "clr-namespace:SilverlightMVVMDemo.Views"
mc:Ignorable = "d"
d:DesignHeight = "576.316" d:DesignWidth = "863.158">
<Grid x:Name = "LayoutRoot" Background = "White">
<views:StudentView x:Name = "StudentViewControl" Loaded = "StudentViewControl_Loaded"/>
</Grid>
</UserControl>
Step 8 - Hier ist die Implementierung von Loaded Veranstaltung in der MainPage.xaml.cs Datei, die die aktualisiert View von dem ViewModel.
using System.Windows;
using System.Windows.Controls;
namespace SilverlightMVVMDemo {
public partial class MainPage : UserControl {
public MainPage() {
InitializeComponent();
}
}
private void StudentViewControl_Loaded(object sender, RoutedEventArgs e) {
SilverlightMVVMDemo.ViewModel.StudentViewModel
studentViewModelObject = new SilverlightMVVMDemo.ViewModel.
StudentViewModel();
studentViewModelObject.LoadStudents();
StudentViewControl.DataContext = studentViewModelObject;
}
}
Step 9 - Wenn der obige Code kompiliert und ausgeführt wird, wird auf Ihrer Webseite die folgende Ausgabe angezeigt.
UI vs ViewModel
Einer der schwierigsten Teile des MVVM-Ansatzes besteht darin, herauszufinden, wo die Trennlinie liegen soll. Es ist nicht immer klar, welche Dinge wohin gehören.
Insbesondere bieten einige Elemente der Benutzeroberfläche Funktionen, die nach einer strengen Ansicht wohl in das ViewModel gehören sollten.
Im Allgemeinen sind nicht alle Verhaltensweisen in der implementiert View sind so ViewModel freundlich.
Ein Grund dafür ist, dass es keine Standardmethode zum Packen des ViewModel-Verhaltens zur Wiederverwendung gibt, insbesondere nicht, wenn Sie eine Entwurfsumgebung wie Visual Studio oder Blend verwenden möchten.
Vorteile von MVVM
MVVM bietet folgende Vorteile:
Trennung von Präsentationsproblemen (View, ViewModel, Model)
Reinigen Sie testbaren und verwaltbaren Code. Kann die Logik der Präsentationsebene in Unit-Tests einbeziehen.
Kein Code hinter dem Code, daher sind die Präsentationsschicht und die Logik lose miteinander verbunden.
Bessere Art der Datenbindung.
Nachteile von MVVM
Für einfache Benutzeroberflächen kann MVVM ein Overkill sein. Das Debuggen wäre etwas schwierig, wenn wir komplexe Datenbindungen haben.