Es sieht so aus, als wären Sie in einige der häufigsten Fallen geraten, aber keine Sorge, sie können behoben werden :)
Zuerst müssen Sie Ihre Anwendung etwas anders betrachten und sie in Teile zerlegen. Wir können die Stücke in zwei Richtungen teilen. Zuerst können wir die Steuerungslogik (die Geschäftsregeln, den Datenzugriffscode, den Benutzerrechtecode, all diese Dinge) vom UI-Code trennen. Zweitens können wir den UI-Code in Teile zerlegen.
Also werden wir den letzten Teil zuerst machen und die Benutzeroberfläche in Teile zerlegen. Der einfachste Weg, dies zu tun, besteht darin, ein einziges Host-Formular zu haben, auf dem Sie Ihre Benutzeroberfläche mit Benutzersteuerelementen zusammenstellen. Jedes Benutzersteuerelement ist für einen Bereich des Formulars verantwortlich. Stellen Sie sich vor, Ihre Anwendung hatte eine Liste von Benutzern, und wenn Sie auf einen Benutzer klicken, wird ein Textfeld darunter mit dessen Details gefüllt. Sie können die Anzeige der Benutzerliste von einem Benutzer und die Anzeige der Benutzerdetails von einem zweiten Benutzer steuern lassen.
Der eigentliche Trick dabei ist, wie Sie die Kommunikation zwischen den Steuerungen verwalten. Sie möchten nicht, dass 30 Benutzersteuerelemente im Formular zufällig aufeinander verweisen und Methoden aufrufen.
Sie erstellen also eine Schnittstelle für jedes Steuerelement. Die Schnittstelle enthält die Operationen, die das Steuerelement akzeptiert, und alle Ereignisse, die es auslöst. Wenn Sie an diese App denken, ist es Ihnen egal, ob sich die Listenauswahl im Listenfeld ändert. Sie interessieren sich für die Tatsache, dass sich ein neuer Benutzer geändert hat.
Unter Verwendung unserer Beispiel-App würde die erste Schnittstelle für das Steuerelement, das die Listbox von Benutzern hostet, ein Ereignis mit dem Namen UserChanged enthalten, das ein Benutzerobjekt ausgibt.
Das ist großartig, denn wenn Ihnen die Listbox langweilig wird und Sie eine magische 3D-Zoom-Augensteuerung wünschen, codieren Sie sie einfach auf derselben Oberfläche und schließen Sie sie an :)
Ok, so Teil zwei, die UI-Logik von der Domain-Logik zu trennen. Nun, dies ist ein abgenutzter Pfad und ich würde empfehlen, dass Sie sich das MVP-Muster hier ansehen. Es ist ganz einfach.
Jedes Steuerelement wird jetzt als Ansicht (V in MVP) bezeichnet, und wir haben bereits das meiste behandelt, was oben benötigt wird. In diesem Fall die Steuerung und eine Schnittstelle dafür.
Wir fügen lediglich das Modell und den Moderator hinzu.
Das Modell enthält die Logik, die Ihren Anwendungsstatus verwaltet. Sie kennen das Zeug, es würde in die Datenbank gehen, um die Benutzer zu bekommen, in die Datenbank zu schreiben, wenn Sie einen Benutzer hinzufügen, und so weiter. Die Idee ist, dass Sie dies alles in völliger Isolation von allem anderen testen können.
Der Moderator ist etwas kniffliger zu erklären. Es ist eine Klasse, die sich zwischen dem Modell und der Ansicht befindet. Es wird von der Ansicht erstellt, und die Ansicht wird über die zuvor beschriebene Schnittstelle an den Präsentator übergeben.
Der Moderator muss kein eigenes Interface haben, aber ich erstelle sowieso gerne eines. Legt fest, was der Präsentator explizit tun soll.
Der Präsentator würde also Methoden wie ListOfAllUsers verfügbar machen, mit denen die Ansicht die Liste der Benutzer abruft. Alternativ könnten Sie der Ansicht eine AddUser-Methode hinzufügen und diese vom Präsentator aufrufen. Ich bevorzuge letzteres. Auf diese Weise kann der Präsentator der Listbox jederzeit einen Benutzer hinzufügen.
Der Presenter verfügt auch über Eigenschaften wie CanEditUser, die true zurückgeben, wenn der ausgewählte Benutzer bearbeitet werden kann. Die Ansicht fragt dies dann jedes Mal ab, wenn sie es wissen muss. Möglicherweise möchten Sie bearbeitbare in Schwarz und schreibgeschützte in Grau. Technisch gesehen ist dies eine Entscheidung für die Ansicht, da sie sich auf die Benutzeroberfläche konzentriert. Ob der Benutzer überhaupt bearbeitet werden kann, liegt beim Präsentator. Der Moderator weiß es, weil er mit dem Model spricht.
Verwenden Sie also zusammenfassend MVP. Microsoft bietet SCSF (Smart Client Software Factory) an, das MVP in der von mir beschriebenen Weise verwendet. Es macht auch viele andere Dinge. Es ist ziemlich komplex und mir gefällt nicht, wie sie alles machen, aber es kann helfen.