Haftungsausschluss: In dieser Frage Registerkarte, Seite, ein Dialogfeld bedeutet eigentlich die gleiche Sache, sorry. Meine Ausrede: Ich bin mir nicht sicher, wie das Endprodukt aussehen soll - ein paar einzelne Fenster oder alles in einem.Suchen Sie nach einem großartigen Assistenten-Beispiel, das mit WinForms und/oder einem Ratgeberentwurf implementiert wurde
Ich bin auf der Suche nach einem bestehenden, schwer zu pflegen Assistenten mit WinForms gebacken. Ich muss versuchen, das Aussehen und das Gefühl in etwa gleich zu halten, aber ich muss die interne Logik aufräumen. Insgesamt gibt es 5 Dialoge, die nacheinander (nach Anklicken der Schaltfläche Weiter) nacheinander in einer riesigen Methode angezeigt werden. Der Weg, um hin und her zu springen, ist mit ... 5 oder 6 Labels und GOTOs!
Jetzt ist dieser Assistent linear, kein Baum. Von jedem einzelnen Dialog/jeder Seite sollten Sie höchstens zwei andere aufrufen können. Irgendwie kommt mir eine doppelt verknüpfte Liste in den Sinn. Derzeit gibt es 5 * 4 = 20
mögliche Zustandsübergänge, während nur 2*1 + 3*2 = 8
von ihnen gültig sind. Ich muss goto
s nicht verwenden. Sie sind normalerweise böse, und in diesem Fall sind sie - es ist schwer, dies bereits zu behaupten ... und ich denke daran, eine weitere, sechste Seite hinzuzufügen. Der Grund, warum goto
s da sind, liegt wahrscheinlich daran, dass A) Zeitdruck war, als v. 1.0 gemacht wurde, B) Es war vor 5 Jahren, also die besten Beispiele/Tutorials zu Wizards, die zu dieser Zeit verfügbar waren, waren vielleicht nicht großartig.
Jetzt fragen die meisten Seiten des Assistenten nach Benutzereingaben. Die folgenden Seiten werden gerendert, je nachdem, was der Benutzer eingegeben hat. Wenn der Benutzer auf Seite 3 sagt und entschieden hat, eine Zurück-Taste ganz auf 1 zu setzen, hat er nichts geändert und trifft zweimal auf Weiter, dann sollte sich der Zustand nicht ändern. Änderungen auf Seite x führen jedoch dazu, dass die Inhalte auf den Seiten x + 1 und darüber hinaus ungültig werden. Es gibt jedoch Ausnahmen, da einige oder alle Einstellungen auf einer Seite x von Seite x-1, x-2 usw. abhängen können, aber die Seiten x + 1, x + 2 usw. hängen nicht von diesem x ab etwas x.
Ich hoffe, die Dinge sind soweit klar. Wir versuchen, dem Benutzer zu helfen, indem wir einige Sachen für sie in Verzug setzen. Die Art und Weise, wie Dinge gelagert werden, ist auch nicht großartig. Der Dialog hat Lese-/Schreibeigenschaften, von/zu denen die Daten zu den aktuellen Steuerelementen kopiert werden. Dann gibt es in der Hauptmethode einen "Superspeicher", der Speicher für jede Seite enthält. Wenn also der Benutzer mit der Seite x fertig ist und die nächste trifft, wird der Inhalt zuerst von den Steuerelementen in den Speicher kopiert, der für die Klasse lokal ist, und dann wird dieser Inhalt in das entsprechende Element des Superspeichers gespeichert.
Arrays (von Dialogen/Speichern) und Indizes werden nicht verwendet. Es gibt separate, aber ähnliche "create & populate" -Logik für jedes goto Ziel (Label). Die Dialogobjekte werden weggeworfen, wenn die Seite nicht mehr angezeigt wird (sie werden nicht entfernt, aber jedes Mal, wenn sie angezeigt werden sollen, werden sie neu erstellt und neu bevölkert. Ich glaube nicht, dass dies notwendig ist, da nur ein Single Handle ist erforderlich, und nachdem es gezeigt und geschlossen wurde, glaube ich, dass es wieder in demselben Zustand gezeigt werden kann, ohne die Steuerelemente neu auffüllen zu müssen. Wenn das Verschwenden von Speicher das einzige Problem wäre, würde ich wahrscheinlich Dinge rutschen lassen, aber die Sache ist nicht sehr wartbar, so könnte ich auch reparieren sie alle auf
ich denke:.
- Shop Dialoge in einer Sammlung, wie ein Array, aber vorzugsweise DLL, weil ich kann nur Vorwärts 1 oder Rückwärts 1 oder nur eine der beiden Optionen Ich habe aufgelistet (für den ersten und letzten Dialog).
- Eigentlich haben meine Tabs/Pages alle eine gemeinsame abstrakte Klasse (da "next", "back", "exit" buttons und ihr Verhalten allen gemeinsam sind).
- Jede Registerkarte/Seite/Dialog (das gleiche für den Zweck dieser Frage, sorry für Verwirrung) wird Lese-Eigenschaften für die "Leiter" -Klasse sichtbar haben.Diese Eigenschaften werden von den Werten in den Steuerelementen (der wahren Informationsquelle) abgeleitet, manchmal werden die Eigenschaften diese Werte etwas massieren. Es liegt in der Verantwortung des "Dirigenten", diese zu ergreifen und einzulagern. Wenn der Leiter den Dialog mit einer einzigen Methode füllen möchte (nennen wir es "Seed"). Ich habe hier ein bisschen Schwierigkeiten, da die Parameter für jede Samenmethode unterschiedlich sein werden. Ich möchte in der Lage sein, sowohl das starke Tippen als auch die generischen Dinge zu nutzen. Ich vermute, dass etwas geben sollte. Ich könnte ein Wörterbuch an jede Samenmethode weitergeben, aber das fühlt sich zu pythonisch an, wie das Tippen von Enten. Ich würde es bis zur Laufzeit nicht wissen, wenn ich es vermassele. Auch das Packen und Entpacken des Wörterbuchs passt immer besser zu jeder Seite. Hier kommen Sie rein.
- Der globale Speicher kann ein riesiges Wörterbuch sein. Ich kann diszipliniert genug sein, um alle Schlüssel unterschiedlich zu halten, oder ihren Namen je nach Seite mit "p1_" bis "p5_" voranstellen, um sicher zu gehen. Ich bin mir sicher, dass es auch andere Systeme gibt. Auf ein riesiges Wörterbuch zu haben kann am Ende ganz praktisch sein - da ist die Reihenfolge, in der die Benutzereingaben zusammengefügt wurden, nicht von Bedeutung, solange es richtig gemacht wird. Ich kann auch eine Zustandsmaschine haben ... irgendwie. Hier verliere ich mich auch im Design. Wenn ich Dinge in einem Wörterbuch aufbewahre, müsste ich eine Menge bedingter Logik ausführen, wie zum Beispiel: Wenn ich auf Seite 2 bin, und ich eine Änderung mache, dann muss ich normalerweise (es gibt Ausnahmen) alte Vorgaben machen, wenn beliebig für Seiten 3,4,5 ungültig. Je nachdem, wie hässlich es ist, ist es vielleicht nicht viel besser als das aktuelle goto-basierte Design. Ich denke jedoch, dass ich es besser machen kann, da ich meine zustands- oder zustandsübergangsspezifische Logik mit einer Reihe von Delegierten implementieren kann, die in zwei Wörterbüchern gespeichert sind (eines für das nächste, eines für das Zurück), wobei der aktuelle Zustand das ist Schlüssel.
Wie Sie sehen können, gibt es ein paar Herausforderungen. Ich bin jedoch hoffnungsvoll, weil das Denken durch ein gutes Wizard-Design ein Rad ist, das vorher sicherlich erfunden wurde. Vielleicht können Sie eine Open-Source-C#/Mono-App empfehlen, die mit einem linearen, aber nicht trivialen Wizard ausgeliefert wird, damit ich einen Blick auf die Implementierung werfen kann. Heck, vielleicht sogar Java/Swing wird mir wahrscheinlich passen, solange der Wizard in der Natur ähnlich ist. WPF wäre eine weitere Herausforderung für mich, ich möchte nicht 2 Probleme anstelle von 1 haben.
Lassen Sie mich wissen, was Sie sich vorstellen können. Sollte ich nur die Gotos behalten, aber andere Teile so gut wie möglich aufräumen? Fühlen Sie sich frei, Fragen zu stellen. Danke,
-HG
Hm ... so muss jede "Seite" wissen, was alle anderen sind. Ich denke darüber nach, dass ich eine "Seite" aktualisieren kann, nachdem sie mit neuen wichtigen Informationen versehen wurde, und lasse die Seite alle wichtigen Informationen zurückgeben, nach denen gefragt wurde. Dann eine Art von Controller von außen ... –
Die Seite ist in der besten Position, um zu "wissen", was Benutzer auf dieser Seite sehen müssen, und um zu wissen, welche Informationen dazu benötigt werden. Und die Seite benötigt alle Informationen, die sie benötigt :-). Es gibt keinen Grund, Informationen von der Seite zu verstecken, da es nicht notwendig ist, das Ganze übermäßig modular zu machen. Das heißt, es sei denn, Sie möchten "Module" in einem anderen Projekt wiederverwenden. In dieser Lösung können Sie die Seite immer noch aktualisieren, und tatsächlich sollten Sie jedes Mal aktualisieren, wenn die Seite angezeigt wird. Aber, wenn Sie eine Lösung im Sinn haben, dann gehen Sie einfach dafür. – Dialecticus