Ich arbeite derzeit mit der Microsoft MVVM-Vorlage und finde das Fehlen detaillierter Beispiele frustrierend. Das mitgelieferte ContactBook-Beispiel zeigt nur sehr wenig Befehlshandhabung. Das einzige andere Beispiel, das ich gefunden habe, stammt aus einem Artikel des MSDN-Magazins, in dem die Konzepte ähnlich sind, jedoch einen etwas anderen Ansatz verwenden und dennoch keine Komplexität aufweisen. Gibt es anständige MVVM-Beispiele, die zumindest grundlegende CRUD-Operationen und das Umschalten von Dialogen / Inhalten zeigen?
Alle Vorschläge waren wirklich nützlich und ich werde anfangen, eine Liste guter Ressourcen zusammenzustellen
Frameworks / Vorlagen
Nützliche Artikel
- WPF-Apps mit dem Model-View-ViewModel-Entwurfsmuster
- Datenüberprüfung in .NET 3.5
- Verwenden eines ViewModel zum Bereitstellen aussagekräftiger Validierungsfehlermeldungen
- Aktionsbasierte ViewModel- und Modellvalidierung
- Dialoge
- Befehlsbindungen in MVVM
- Mehr als nur MVC für WPF
- MVVM + Mediator Beispielanwendung
Screencasts
Zusätzliche Bibliotheken
- Die verbesserte Implementierung des Mediator-Musters von WPF Disciples (ich empfehle dies dringend für Anwendungen mit komplexerer Navigation).
- MVVM Light Toolkit Messenger
Antworten:
Leider gibt es keine großartige MVVM-Beispiel-App, die alles kann, und es gibt viele verschiedene Ansätze, um Dinge zu tun. Zunächst möchten Sie sich vielleicht mit einem der App-Frameworks vertraut machen (Prism ist eine gute Wahl), da es Ihnen praktische Tools wie Abhängigkeitsinjektion, Befehle, Ereignisaggregation usw. bietet, mit denen Sie auf einfache Weise verschiedene Muster ausprobieren können, die zu Ihnen passen .
Die Prismenfreigabe:
http://www.codeplex.com/CompositeWPF
Es enthält eine ziemlich anständige Beispiel-App (den Aktienhändler) sowie viele kleinere Beispiele und Anleitungen. Zumindest ist es eine gute Demonstration einiger gängiger Untermuster, mit denen MVVM tatsächlich funktioniert. Ich glaube, sie haben Beispiele für CRUD und Dialoge.
Prisma ist nicht unbedingt für jedes Projekt geeignet, aber es ist eine gute Sache, sich damit vertraut zu machen.
CRUD: Dieser Teil ist ziemlich einfach. WPF-Zweiwege-Bindungen machen es wirklich einfach, die meisten Daten zu bearbeiten. Der eigentliche Trick besteht darin, ein Modell bereitzustellen, mit dem die Benutzeroberfläche einfach eingerichtet werden kann. Zumindest möchten Sie sicherstellen, dass Ihr ViewModel (oder Geschäftsobjekt) implementiert wird
INotifyPropertyChanged
, um die Bindung zu unterstützen, und Sie können Eigenschaften direkt an UI-Steuerelemente binden, aber Sie möchten sie möglicherweise auchIDataErrorInfo
zur Validierung implementieren . Wenn Sie eine ORM-Lösung verwenden, ist das Einrichten von CRUD in der Regel ein Kinderspiel.Dieser Artikel beschreibt einfache Rohoperationen: http://dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx
Es basiert auf LinqToSql, aber das ist für das Beispiel irrelevant - alles, was wichtig ist, ist, dass Ihre Geschäftsobjekte implementiert werden
INotifyPropertyChanged
(welche Klassen von LinqToSql generiert werden). MVVM ist nicht der Punkt dieses Beispiels, aber ich denke nicht, dass es in diesem Fall wichtig ist.Dieser Artikel demonstriert die Datenvalidierung
http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx
Wiederum generieren die meisten ORM-Lösungen Klassen, die bereits implementiert sind
IDataErrorInfo
und normalerweise einen Mechanismus bieten, der das Hinzufügen benutzerdefinierter Validierungsregeln erleichtert.Meistens können Sie ein von einem ORM erstelltes Objekt (Modell) in ein ViewModel einbinden, das es und Befehle zum Speichern / Löschen enthält - und Sie können die Benutzeroberfläche direkt an die Eigenschaften des Modells binden.
Die Ansicht würde ungefähr so aussehen (ViewModel hat eine Eigenschaft
Item
, die das Modell enthält, wie eine im ORM erstellte Klasse):Dialoge: Dialoge und MVVM sind etwas knifflig. Ich bevorzuge es, eine Variante des Mediator-Ansatzes mit Dialogen zu verwenden. Weitere Informationen hierzu finden Sie in dieser StackOverflow-Frage:
Beispiel für einen WPF MVVM-Dialog
Mein üblicher Ansatz, der nicht ganz klassisch MVVM ist, kann wie folgt zusammengefasst werden:
Eine Basisklasse für ein Dialogfeld ViewModel, das Befehle zum Festschreiben und Abbrechen von Aktionen bereitstellt, ein Ereignis, mit dem die Ansicht darüber informiert wird, dass ein Dialogfeld zum Schließen bereit ist, und alles, was Sie sonst noch in all Ihren Dialogfeldern benötigen.
Eine allgemeine Ansicht für Ihren Dialog - Dies kann ein Fenster oder ein benutzerdefiniertes "modales" Overlay-Typ-Steuerelement sein. Im Kern handelt es sich um einen Content Presenter, in den wir das Ansichtsmodell kopieren, und der die Verkabelung zum Schließen des Fensters übernimmt. Beispielsweise können Sie bei Änderungen des Datenkontexts überprüfen, ob das neue ViewModel von Ihrer Basisklasse geerbt wurde und ob dies der Fall ist. Abonnieren Sie das entsprechende Abschlussereignis (der Handler weist das Dialogergebnis zu). Wenn Sie eine alternative universelle Schließfunktion bereitstellen (z. B. die Schaltfläche X), sollten Sie sicherstellen, dass Sie den entsprechenden Befehl zum Schließen auch im ViewModel ausführen.
Wenn Sie Datenvorlagen für Ihre ViewModels bereitstellen müssen, können diese sehr einfach sein, insbesondere da Sie wahrscheinlich eine Ansicht für jeden Dialog haben, der in einem separaten Steuerelement gekapselt ist. Die Standarddatenvorlage für ein ViewModel würde dann ungefähr so aussehen:
Die Dialogansicht muss Zugriff auf diese haben, da sie sonst nicht weiß, wie das ViewModel angezeigt werden soll. Abgesehen von der Benutzeroberfläche des freigegebenen Dialogfelds sind die Inhalte im Wesentlichen folgende:
Die implizite Datenvorlage ordnet die Ansicht dem Modell zu, aber wer startet sie?
Dies ist der nicht so mvvm Teil. Eine Möglichkeit besteht darin, ein globales Ereignis zu verwenden. Ich denke, es ist besser, ein Ereignisaggregatortyp-Setup zu verwenden, das durch Abhängigkeitsinjektion bereitgestellt wird. Auf diese Weise ist das Ereignis für einen Container global und nicht für die gesamte App. Prism verwendet das Unity-Framework für die Containersemantik und die Abhängigkeitsinjektion, und insgesamt gefällt mir Unity ziemlich gut.
Normalerweise ist es sinnvoll, dass das Stammfenster dieses Ereignis abonniert. Es kann den Dialog öffnen und seinen Datenkontext auf das ViewModel festlegen, das mit einem ausgelösten Ereignis übergeben wird.
Wenn Sie dies auf diese Weise einrichten, können ViewModels die Anwendung auffordern, ein Dialogfeld zu öffnen und dort auf Benutzeraktionen zu reagieren, ohne etwas über die Benutzeroberfläche zu wissen, sodass die MVVM-Funktion größtenteils vollständig bleibt.
Es gibt jedoch Situationen, in denen die Benutzeroberfläche die Dialoge öffnen muss, was die Dinge etwas schwieriger machen kann. Überlegen Sie beispielsweise, ob die Dialogposition von der Position der Schaltfläche abhängt, mit der sie geöffnet wird. In diesem Fall benötigen Sie einige UI-spezifische Informationen, wenn Sie ein geöffnetes Dialogfeld anfordern möchten. Im Allgemeinen erstelle ich eine separate Klasse, die ein ViewModel und einige relevante UI-Informationen enthält. Leider scheint dort eine gewisse Kopplung unvermeidlich.
Pseudocode eines Schaltflächenhandlers, der einen Dialog auslöst, der Elementpositionsdaten benötigt:
Die Dialogansicht wird an Positionsdaten gebunden und das enthaltene ViewModel an das Innere übergeben
ContentControl
. Das ViewModel selbst weiß immer noch nichts über die Benutzeroberfläche.Im Allgemeinen verwende ich die
DialogResult
return-Eigenschaft derShowDialog()
Methode nicht und erwarte nicht, dass der Thread blockiert, bis der Dialog geschlossen wird. Ein nicht standardmäßiger modaler Dialog funktioniert nicht immer so, und in einer zusammengesetzten Umgebung möchten Sie oft nicht, dass ein Ereignishandler sowieso so blockiert. Ich ziehe es vor, die ViewModels damit befassen zu lassen - der Ersteller eines ViewModels kann seine relevanten Ereignisse abonnieren, Commit / Cancel-Methoden festlegen usw., sodass Sie sich nicht auf diesen UI-Mechanismus verlassen müssen.Also anstelle dieses Flusses:
Ich benutze:
Ich bevorzuge es auf diese Weise, da die meisten meiner Dialoge nicht blockierende pseudomodale Steuerelemente sind und es einfacher erscheint, dies zu tun, als es zu umgehen. Einfach zu testen.
quelle
Jason Dolinger hat einen guten Screencast von MVVM gemacht. Wie Egor erwähnt hat, gibt es kein gutes Beispiel. Sie sind alle vorbei. Die meisten sind gute MVVM-Beispiele, aber nicht, wenn Sie in komplexe Probleme geraten. Jeder hat seinen eigenen Weg. Laurent Bugnion hat auch eine gute Möglichkeit, zwischen Ansichtsmodellen zu kommunizieren. http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch ist ebenfalls ein gutes Beispiel. Paul Stovel hat einen guten Beitrag , der auch mit seinem Magellan-Framework viel erklärt.
quelle
Hast du dir Caliburn angesehen ? Das ContactManager-Beispiel enthält viele gute Inhalte. Die generischen WPF-Beispiele bieten auch einen guten Überblick über Befehle. Die Dokumentation ist ziemlich gut und die Foren sind aktiv. Empfohlen!
quelle
Fand dieses nützlich. Hat auch Code.
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
quelle
Hier füge ich einen Link einer WPF-Anwendung (Inventory Management App) hinzu, die die von mir entworfene MVVM-Architektur verwendet .
Die Benutzeroberfläche ist fantastisch. https://github.com/shivam01990/InventoryManagement
quelle
Das Beispielprojekt im Cinch-Framework zeigt grundlegende CRUD- und Navigationswerkzeuge. Es ist ein ziemlich gutes Beispiel für die Verwendung von MVVM und enthält einen mehrteiligen Artikel , in dem die Verwendung und die Motivationen von MVVM erläutert werden.
quelle
Ich teilte auch Ihre Frustration. Ich schreibe eine Bewerbung und hatte diese 3 Anforderungen:
Alles, was ich fand, waren Kleinigkeiten, also fing ich gerade an, es so gut ich konnte zu schreiben. Nachdem ich mich ein wenig damit beschäftigt hatte, wurde mir klar, dass es möglicherweise andere Leute (wie Sie) gibt, die eine Referenzanwendung verwenden könnten. Deshalb habe ich das generische Material in ein WPF / MVVM-Anwendungsframework umgestaltet und es unter der LGPL veröffentlicht. Ich habe es SoapBox Core genannt . Wenn Sie zur Downloadseite gehen, wird eine kleine Demoanwendung mitgeliefert, und der Quellcode für diese Demoanwendung steht auch zum Download zur Verfügung. Ich hoffe, Sie finden das hilfreich. Senden Sie mir auch eine E-Mail an scott {at} soapboxautomation.com, wenn Sie weitere Informationen wünschen.
BEARBEITEN : Außerdem wurde ein CodeProject-Artikel veröffentlicht , in dem die Funktionsweise erläutert wird.
quelle
Ich habe ein einfaches MVVM-Beispiel von Grund auf für ein Code-Projekt geschrieben. Hier ist der Link MVVM WPF Schritt für Schritt . Es geht von einer einfachen 3-Schicht-Architektur aus und bietet Ihnen die Möglichkeit, ein Framework wie PRISM zu verwenden.
quelle
Sogar ich teilte die Frustration, bis ich die Angelegenheit in meine Hände nahm. Ich habe IncEditor gestartet.
IncEditor ( http://inceditor.codeplex.com ) ist ein Editor, der versucht, Entwicklern WPF, MVVM und MEF vorzustellen. Ich habe es gestartet und es geschafft, einige Funktionen wie "Theme" -Unterstützung zu erhalten. Ich bin kein Experte für WPF, MVVM oder MEF, daher kann ich nicht viele Funktionen einbauen. Ich bitte euch aufrichtig, es besser zu machen, damit Verrückte wie ich es besser verstehen können.
quelle