Ist es empfehlenswert, Benutzersteuerelemente zum Strukturieren von WPF-Formularen zu verwenden, auch wenn diese Benutzersteuerelemente nur einmal verwendet werden?


8

Ich entwickle eine WPF-Anwendung mit MVVM und lerne, wie man Dinge am besten macht.

Ich habe ein WPF-Formular mit Selektoren, zwei Listen mit Suchfeldern und einige andere Elemente. Derzeit ist alles in einer Form und es funktioniert. Inzwischen hat die VM für dieses Formular mehr als 800 Zeilen und ist noch nicht fertig.

Ich möchte dieses Formular und den Code besser strukturieren. Ich dachte an Regionen, Dateien mit Teilklassen und Benutzersteuerelemente. Ich denke, Benutzersteuerelemente sind am besten geeignet, da sie einige Steuerelemente und Logik enthalten. Wenn ich Benutzersteuerelemente verwenden würde, würde die Menge an Code in diesem Fenster und in der VM drastisch reduziert.

Um dies richtig zu machen, arbeite ich das Buch "Pro WPF 4.5 In C # 4th Edition", Kapitel 18 - Benutzerdefinierte Elemente und das ColorPickerUserControl-Beispiel durch. Das Beispiel handelt von einem Farbwähler mit drei Schiebereglern und 150 Codezeilen.

Ich denke, ich verstehe, wie es funktioniert, aber es scheint mir, dass das Erstellen von Benutzersteuerelementen selbst mit sehr eingeschränkten Funktionen wie in diesem Beispiel eine Menge Arbeit ist . Wenn ich diese Steuerelemente mehrmals verwenden würde, wäre es meines Erachtens sinnvoll, dies zu tun. Aber wenn ich die Steuerelemente nur einmal benutze und dies nur tue, um meine Form zu strukturieren, dann scheint dies eine Menge Arbeit für wenig Gewinn zu sein.

Meine Frage lautet: Ist es empfehlenswert, Benutzersteuerelemente zum Strukturieren von Formularen zu verwenden, auch wenn diese Benutzersteuerelemente nur einmal verwendet werden? Wenn nicht, gibt es eine bessere Alternative?

Bearbeiten (nicht zum Lesen erforderlich, nur weitere Informationen): Bis jetzt habe ich keine Details geschrieben, weil ich etwas über das Prinzip lernen wollte, aber nachdem ich 17 von 26 der interessanten Antwort gelesen habe, sind hier einige Details: Dieses Formular dient zur Auswahl von Musiktiteln.

  • Gruppe A: (mögliche Benutzersteuerung A) bezieht sich auf die Art der Auswahl wie Auswahl nach Künstler oder Album, mit oder ohne Video, möglicherweise Erscheinungsjahr usw.

  • Gruppe B: Diese Liste enthält Künstlernamen, die nach den Kriterien in A gefiltert werden. Der Benutzer kann die Liste filtern, dh nur Künstlernamen anzeigen, die "top" enthalten.

  • Gruppe C: Diese Liste zeigt Titel des in B ausgewählten Künstlers auch nach Kriterien von A (dh Audio oder Video). Es kann ähnlich wie B gefiltert werden, dh nur Titel, die "Sie" enthalten.

Der größte Teil der Logik findet in der VM statt (DataContext des Formulars). Die Listen von A und B stammen aus einer Datenbank. Die Listen werden gefiltert und für die Präsentation vorbereitet (dh mehrere Titel mit demselben Namen, jedoch in unterschiedlichen Alben). Der Benutzer wählt einen Titel in der C-Liste durch Doppelklick aus oder verwendet Drag & Drop in ein anderes WPF-Formular.

Was ich will: Ich möchte lesbaren Code, damit ich ihn leicht ändern kann. Wenn ich einen weiteren Filter hinzufügen möchte, z. B. nur Künstlerinnen anzeigen möchte, wäre es gut, wenn ich einfach zur Benutzersteuerung A gehen und Kontrollkästchen für Künstlerinnen und / oder Künstlerinnen hinzufügen könnte.

Die XAML in der aktuellen Form ist kein Problem, sie ist gut strukturiert. Die VM verfügt jedoch über Code für alle oben genannten Funktionen. Einige Dinge befinden sich im Konstruktor, andere im Befehlsabschnitt, einige Eigenschaften und Hintergrundfelder. Ich kann jetzt noch Dinge finden, aber ich denke, es wäre besser, wenn der Code strukturierter wäre. Deshalb denke ich über die Benutzersteuerelemente nach.

Ich versuche, MVVM zu folgen, weil ich denke, dass die Logik dahinter sehr viel Sinn macht. Aber ich bin kein fanatischer Anhänger einer theoretischen Praxis. Das heißt, wenn ich etwas in 5 Zeilen CodeBehind oder in 50 Zeilen in der VM tun kann, werde ich es wahrscheinlich in CodeBehind tun. Meine Frage betrifft das Prinzip, wie strukturierte Formulare in WPF erstellt werden. Das oben beschriebene Formular ist ein gutes Beispiel, aber die Antwort sollte sich nicht auf dieses einzelne konzentrieren, sondern auf die Idee, wie WPF-Formulare strukturiert werden, dh mit (oder ohne) Benutzersteuerelementen.

Warum ich Benutzersteuerelemente für viel Arbeit halte: Sie haben Abhängigkeitseigenschaften, geroutete Ereignisse usw. All dies scheint mir viel komplizierter zu sein als „normale“ Eigenschaften mit Hintergrundfeldern und INotify. Aber vielleicht muss ich mich nur an Abhängigkeitseigenschaften, geroutete Ereignisse usw. gewöhnen.


Ich bin ein bisschen verwirrt darüber, warum Sie denken, dass das Erstellen von Benutzersteuerelementen eine Menge Arbeit ist. In seiner einfachsten Form ist ein UserControl nur ein Container. Du machst so einen : <UserControl> </UserControl>. Das ist es.
Robert Harvey

In Bezug auf Ihre Bearbeitung: Benutzersteuerelemente verfügen nur dann über Abhängigkeitseigenschaften, geroutete Ereignisse usw., wenn Sie diese Elemente einfügen. Sie sind keinesfalls obligatorisch.
Robert Harvey

@ RobertHarvey: Ja, das verstehe ich. Aber es scheint für "volle Funktionalität" mit bidirektionaler Bindung, die etwas in der Hauptform auslöst, wenn etwas in der Benutzersteuerung geändert wurde, usw. sie sind notwendig. Ich denke, das Beispiel in dem Buch, das ich oben erwähne, zeigt, wie notwendig sie oft (nicht immer) sind.
Edgar

Müssten Sie das alles nicht noch tun, ohne Benutzersteuerelemente zu verwenden?
Robert Harvey

1
Es hört sich auch nicht so an, als würde das ViewModel verdammt viel tun. Das Sortieren und Filtern einer Ergebnisliste ist für ein ViewModel eine relativ kleine Aufgabe. Möglicherweise liegt das Problem nicht darin, was die VM tut, sondern wie sie geschrieben ist. Möglicherweise gibt es einige C # -Funktionen, mit denen Sie die Codegröße reduzieren können. Oder vielleicht kann die VM überarbeitet werden, um ihre Größe zu verringern.
17 von 26

Antworten:


7

Absolut ja. Es ist eine gute Idee, genauso wie es eine gute Idee ist, die Trennung von Bedenken auf Klassen anzuwenden, um jede für sich zu stellen, um eine einzelne Aufgabe auszuführen. Sie haben möglicherweise nur eine Instanz dieser Klasse, aber das spielt keine Rolle. Die Optimierung erfolgt nicht in Bezug auf die Programmleistung, sondern in Bezug auf Organisation und Gesamtprogramm "Gesundheit".

Sie möchten eines Tages zu Ihrem Programm zurückkehren können und nicht durch mehrere hundert Seiten Code scrollen müssen, selbst wenn dieser in Regionen unterteilt ist (die Verwendung von Regionen in Klassen mit viel Code ist wie das Auftragen von Lippenstift auf ein Schwein) Weg). Sollten Sie sich eines Tages entscheiden, es woanders zu verwenden, können Sie dies elegant und ohne viele Probleme tun.

Machen Sie einfach nicht die Versuchung, dem Benutzer die Kontrolle über das übergeordnete Formular zu gewähren. Wenn Sie dies auf diese Weise tun, verwenden Sie Ereignisse, um Informationen an das übergeordnete Formular mit dem übergeordneten Formular als Abonnent zu übermitteln.


Wenn Sie ein benutzerdefiniertes Steuerelement erstellen, können Sie auch den Teil der Präsentationslogik kapseln, für den es verantwortlich ist. Wenn dies richtig gemacht wird, wird Ihre Präsentationslogik im enthaltenen Steuerelement einfacher.
Filip Milovanović

"Absolut ja" ist meiner Meinung nach keine gute Antwort, wenn der Aufwand für die Erstellung eines Benutzersteuerelements so hoch ist, wie es das OP beschreibt.
Doc Brown

1
Ein VIewModel hat ein einziges Anliegen, die Benutzeroberflächenlogik für eine Reihe von Steuerelementen der Benutzeroberfläche zu koordinieren. Das Aufbrechen kann eine Herausforderung sein und macht oft keinen Sinn.
17 von 26

2
@DocBrown Die Frage fragt nach Meinungen zur Praxis im Allgemeinen. Ich denke, Neils Antwort ist fair und eine ehrliche Meinung. Es gibt keine absolute Antwort auf irgendetwas, aber wir können immer empfehlen, irgendwo zu beginnen. IMHO, wenn ich dafür bezahlt würde, es zu codieren, würde ich es richtig machen (Neils Empfehlung). Außerdem kann dies sehr hilfreich sein, wenn Sie Steuerelemente für zukünftige Projekte jemals wiederverwenden möchten. Aber wenn ich nur herumspielen oder mir etwas machen will, mache ich es einfach schneller, weil ich schon mit meiner Wäsche im Rückstand bin.
Christopher

1
"absolut ja" ist falsch. Die richtige Antwort lautet "Es kommt darauf an". Die Aufteilung einer Ansicht / VM in mehrere Ansichten / VMs erhöht die Kosten und die Komplexität. Der Nutzen muss die Kosten überwiegen.
17 von 26

4

Diese Frage ist wirklich schwer zu beantworten, ohne den tatsächlichen Code zu sehen. Sie mischen auch Begriffe ein bisschen. Benutzersteuerelemente sind keine 1: 1-Zuordnung mit ViewModels.

Benutzersteuerelemente haben einen bestimmten Lebenszweck: Sie setzen sich aus mehreren UI-Elementen zusammen, die als Einheit zusammen verwendet werden. Benutzersteuerelemente sind Unterabschnitte einer Ansicht. Dies unterscheidet sich stark von einem ViewModel, das Logik enthält, an die eine Ansicht gebunden ist.

Vielleicht ist es sinnvoll, Ihre XAML in mehrere Benutzersteuerelemente aufzuteilen, die alle von einem einzigen ViewModel gesteuert werden. Vielleicht ist es sinnvoll, Ihren XAML- und C # -Code in mehrere View-VM-Paare aufzuteilen. Vielleicht macht es Sinn, es einfach so zu lassen, wie Sie es jetzt haben. Es ist unmöglich zu sagen, ohne den fraglichen Code zu sehen.

Was ist dein Endziel hier? Verursacht die Größe des Codes tatsächlich Schmerzen oder folgt dies nur einer theoretischen Praxis?

Versuchen Sie, die Größe Ihrer XAML-Ansichten oder die Größe Ihrer C # -Ansichtsmodelle zu verringern? Dies sind zwei sehr unterschiedliche Aufgaben in der WPF MVVM-Welt.

800 Zeilen sind für eine VM, die eine Benutzeroberfläche mit beliebiger Komplexität unterstützt, nicht besonders groß. Das Aufbrechen einer VM kann häufig mehr Probleme verursachen als lösen. ViewModels treffen Entscheidungen wie "Deaktivieren Sie diese Funktion, wenn diese andere Liste leer ist". Der Versuch, diese Art der Entscheidungsfindung auf mehrere Komponenten aufzuteilen, ist oft nicht sinnvoll und erhöht lediglich die Komplexität des Codes.

Nachdem dies gesagt wurde, gibt es möglicherweise Arbeit in der VM, die nichts mit Ihrer ViewModel-Logik zu tun hat und leicht in eine eigene Klasse partitioniert werden kann. Dies würde die Größe des ViewModel verringern, ohne die Gesamtkomplexität des Codes zu erhöhen.

Ich denke, das war nur eine sehr langwierige Art zu sagen: "Es kommt darauf an, und wir können es nicht sagen, ohne den fraglichen Code zu sehen."


Danke für deine Antwort. Ich habe nie darüber gelesen, mehrere View-VM-Paare zu haben - das klingt nach einer interessanten Idee. Im Übrigen habe ich es meiner Frage hinzugefügt.
Edgar

Was ist View in diesem mehrfachen View-VM-Paar(a UserControl/a Grid/a Page ??)
Codename Jack

0

Wenn ich, der ich nichts über Ihre App weiß, ein neues Feld über dem Nachnamenfeld hinzufügen oder die Reihenfolge einiger Felder ändern müsste ... würde ich es einfach oder entmutigend finden?

Ich vertraue nicht auf Regionen, weil der Compiler nicht überprüft, ob Sie etwas in der falschen Region verlegt haben

Sie müssen Software entwickeln, um es den Menschen zu erleichtern, auf dem aufzubauen, was Sie erstellt haben.


Haben Sie jemals ein Formular in WPF erstellt? Wenn ja, sollten Sie wissen, dass Sie das tun würden, was Sie im XAML-Teil des Formulars und nicht im Code dahinter oder in der VM beschreiben. Oder um Ihre Frage zu beantworten: Ja, das wäre sehr einfach.
Edgar

@ Edgar Meine Schuld. Sie haben über visuelle Komponenten und Benutzersteuerungen gesprochen, und ich dachte, das wäre alles. Wenn alle Ihre visuellen Elemente in der Ansicht und Ihre gesamte Geschäftslogik im Modell enthalten sind, sollten Sie sich keine Sorgen über eine lange VM machen.
Ein Bravo Dev
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.