Diskussionsthread: WinForms Projektentwicklung bzgl. der Rolle des Formulars

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von Amro.

    Diskussionsthread: WinForms Projektentwicklung bzgl. der Rolle des Formulars

    ausgelagert aus WinForms Projektentwicklung bzgl. der Rolle des Formulars ~VaporiZed

    Amro schrieb:

    Erstell das ganze erst in WPF und MVVM.
    Leichter gesagt als getan, da ich von WPF null Plan hab. Also mein XAML-Code sieht zum <X aus. Aber es klappt - zumindest bis auf das Schließen.
    Überrascht hat mich nur, dass im ViewModel bei WinForms OnPropertyChanged für eine Property reicht, um alle zu aktualisieren, in der WPF muss ich es für jede einzelne Property machen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Nehmen wir an du hast in WPF zwei getrennte Projekte. Views und ViewModels. Das ViewModel kennt keine Views also musst du mit Service/Interface arbeite. In deiner Views legst du am einfachsten einen Service an der das für dich übernimmt.
    Jetzt stehst du vor dem Problem, du musst diese ViewModel(wpf) in Windows Forms übernehmen. Aber das ViewModel aus der WPF kennt kein DialogResult oder sonst was aus WindowsForms.
    Soll es auch gar nicht kennen,das soll sich ja nur um Daten kümmer und nicht um die UI oder Views.
    Dafür kennt es vielleicht ein IDialogService der sich in einem Core Projekt befindet oder so. Dem Viewmodel ist das Egal Wo das IDialogService herkommt, ob aus WPF oder WindowsForms oder sonst woher. Es kann diesen Ausführen und was der macht ist ihr auch egal.

    Hab dein Projekt etwas überarbeitet und hier mein Vorschlag, ganz einfach gehalten.
    Ich bin auch nicht so gut in der Programmierung da ich alles nur Hobbymässig betreibe.
    Aber so würde ich es machen.
    Man müsste es genau testen in verschiedenen Projekten um zu sehen ob es funktioniert.
    Ist nur für das Verständnis. Man kann darauf Aufbauen glaub ich.
    Es geht noch besser wenn man sich da die zeit nimmt und es besser durchdenkt mit den Service.
    Dateien
    • MVVM.zip

      (187,85 kB, 182 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Amro“ ()

    Achso, Du meinst, dass eben dann ein passender DialogService für das View bereit gestellt werden muss und das ViewModel unabhängig davon bleibt und einfach nur indirekt dem WinForms-DialogService bescheid gibt: "Mach mal." und die eigentliche Arbeit auf ihn abwälzt. Ja, sowas hatte ich auch kurz im Unsinn, ob das der Weg ist, da mir mal vor ein paar Jahren Nofear23m ein kleines Projekt für mich zusammengebastelt hatte. Aber mir fehlte bis heute die Muße, sein Ergebnis genau zu analysieren, weil ich damals maßlos von den ganzen MVVM-Komponenten überfordert war.
    Ich fasse zusammen: DialogService ans View anpassen und abstrakt dem VM bekannt geben. Der DialogService kümmert sich ums Form oder das WPF-Window.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Ich fasse zusammen: DialogService ans View anpassen und abstrakt dem VM bekannt geben. Der DialogService kümmert sich ums Form oder das WPF-Window.

    Genau so hab ich es mir gedacht. Wenn du das Muster beibehälst wird es nachher für den DI-Container sehr Hilfreich sein.
    Alles was von aussen kommt sollte über ein Service kommen. Überleg mal, Net Maui kennt keine Usercontrols und WPF kennt keine Forms und Blazor und WInUi und was es da noch so gibt. Also alles was die UI angeht über Interfaces und Services. Den Service kannst du ja jedezeit austauschen solang er das Interface implementiert .Du willst ja deine ViewModels nur einmal schreiben und nachher in verschiedenen Projekten benutzen. Also vielleicht eine APP oder in Wpf oder in WindowsForms wie gerade eben. Da kann das ViewModel nicht Dinge mitbringen die aus eine anderen UI-Technologie stammen.

    Und wenn es sein muss machst du es halt in der View im Code Behind , ist ok wenn es nur der grafischen Darstellung dient.Das verwirrt die Leute immer.
    Ist Geschmacksache aber sollte keine feste Regel sein.
    Gerade am Anfang , wenn man es nicht übertreibt ;)

    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „Amro“ ()

    Jou, genau, das war eben noch der Denkfehler. Also: Wegabstrahieren, was nicht generisch ist. Vielen Dank.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Aber ist es nicht bei jedem VB6/VB.NET Anfänger so, dass man mit Winforms beginnt und dann den kompletten Code (meist aus Unwissenheit) direkt in der Form verwaltet?

    Ich habe nie programmieren gelernt. Ich habe ca. 2002 mit VB6 meine ersten Versuche gewagt.

    2005 habe ich meine erste Kassensoftware mit VB6 geschrieben und diese Software hat sich 13 Jahre lang am Markt etabliert - obwohl in VB6 und der meiste Code in den Forms.

    2020 habe ich bereits die dritte Version mit VB.NET 4.5 ebenfalls in Winforms herausgebracht. Hier ist nur noch ganz wenig Code in der Form selbst. Das meiste wurde bereits in Modulen (Klassen sind "noch" nicht so meins") untergebracht.

    2023 habe ich es dann aber von Grund auf richtig gemacht und Code und GUI getrennt. Aber auch hier wieder nur mit Winforms. Obwohl man der Anwendung das Winforms gar nicht mehr ansieht.
    Die runden Buttons in der BOPV.uno Anwendung sind tatsächlich echte Button-Controls mit dem Verhalten von Buttons. Zeichnen mit e.graphics ist jetzt auch kein Schreckgespenst mehr und in dieser Anwendung werkeln sogar über 10 Background-Worker.

    WPF habe ich mir kurz mal angesehen - ist aber für mich zu abstrakt und ich kann mich da nicht wirklich umgewöhnen. Aber solange ich alles auch mit Winforms hinbekomme, ist es für mich ok.

    Auf diesem Wege möchte ich mich auch herzlich bei allen hier im Forum bedanken. Durch Euch habe ich sehr viel gelernt. Hoffentlich konnte ich auch hie und da etwas mit kleinen Tipps zurückgeben.

    Bilder
    • Winforms_jaauch.jpg

      104,01 kB, 354×766, 49 mal angesehen
    • Winforms2005.gif

      48,17 kB, 808×589, 87 mal angesehen
    • Winforms2020.jpg

      367,04 kB, 1.010×761, 58 mal angesehen
    • Winforms2023.jpg

      509,89 kB, 1.280×720, 56 mal angesehen
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    dive26 schrieb:

    Aber ist es nicht bei jedem VB6/VB.NET Anfänger so, dass man mit Winforms beginnt und dann den kompletten Code (meist aus Unwissenheit) direkt in der Form verwaltet?
    Richtig. Und genau deshalb, hatte ich damals den Thread aufgemacht, um bessere Wege zu zeigen. Weil viele sich nämlich in Spaghetticode verheddern, nicht mehr rauskommen und dann entweder frustriert aufgeben oder von anderen den Kopf gewaschen bekommen. Du bist jetzt seit 20 Jahren dabei und hast fantastisch guttaussehende und sicherlich genauso funktionierende Apps hinbekommen. Aber das ist ja nicht für alle ein gangbarer Weg. Ich wollte verhindern, dass viele Anfänger, die sich weder Jahrzehnte Zeit nehmen wollen, noch einen Mentor haben, der ihnen zeigt, wie es geht, den Bach runtergehen oder sich in Nudeln mit Tomatensauße verirren. Dass man mit WinForms super Sachen hinbekommt, stell ich nicht infrage. Es ging mir um die Erstellung einer sauberen Projektgrundlage und welche Rollen das Formular in einem Projekt annehmen kann. Und somit wollte ich zeigen, dass das Form eben nicht alles können und wissen muss. MVP und MVVM sind dafür m.E. eben gute Beispiele. Dass Du sehr viel aus der GUI-Klasse entfernen konntest, finde ich erstrebenswert. Ich wollte mit dem Tipps&Tricks-Thread damals zeigen, welche Möglichkeiten es dafür gibt bzw. welche sich m.E. generell dafür etabliert haben. Ob ich immer das nach dem jeweiligen Muster erfüllt hatte, weiß ich allerdings nicht.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Nicht dass wir uns falsch verstehen. Das ist eine Quick and Dirty Lösung, die nur den Weg aufzeigen soll und nur für WinForms und Momentan gedacht ist.
    Normalerweise sollte man sowas vermeiden und stattdessen Techniken wie CommandParameter oder andere Methoden verwenden.
    Bei mir hat das mit CommandParameter in WindowsForms nicht funktioniert.
    Es ist gut möglich das Binding in WindowsForms noch nicht ausgereift ist.
    Vielleicht kommt das noch mit den CommandParameter.
    Wenn jemand weiß wie man CommandParameter angibt kann man den Service so umbauen das
    die Form über CommandParameter eingereicht wird. Das wäre dann evt. ein bessere Lösung.
    Man kann auch evt. das DialogResult der Form direkt an die Property des DialogService binden und Manipulieren...

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Amro“ ()

    Das mit Command und CommandParameter klappt schon. Man muss nur mindestens .NET 7 einstellen. Bei .NET 8 klappt es ohne weitere Angaben, bei .NET 7 muss man ein wenig nachhelfen, siehe
    Diskussionsthread: MVVM mit WinForms - kleiner Einstieg für Anfänger
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Amro schrieb:

    kann man den Service so umbauen das...


    mal dumm dazwischengefragt: Was versteht ihr unter "Service"?
    Bei mir gibts Services als Bestandteil einer Server-Client-Netz-Architektur, da kann sein, dass ein Service mw. bestimmte Anfragen beantwortet, indem er Daten zurückschickz.
    Also Service hat bei mir was mit Netzwerken zu tun, mehrere Anwendungen, und Daten herumschicken.

    Einen Dielog von einem Service abrufen - das geht über meinen Horizont. Bei mir sind Dialoge Bestandteil der Client-Anwendung, und kann man keinesfalls iwo anders hin verfrachten, und dann abrufen.
    ein Dialog ist ja kein Datenpaket.
    Ich kann dazu nicht viel sagen, da ich mit der detaillierten MVVM-Geschichte, v.a. in der WPF noch überfordert bin. Ich hab mir das aus den Beispielen von @Nofear23m und @Amro so zusammengereimt, dass es Helferklassen sind, die je nur einen Zweck erfüllen. In dem Fall ist der DialogService wohl dazu da, um in der WPF ein leeres DialogWindow mit einem UserControl mit dem eigentlichen Inhalt erzeugen und dies anzuzeigen und zu schließen. In WinForms verwendet @Amro den DialogService, um eben auf Anweisung des MainViewModels das MainForm zu schließen. Oder als weitere Ausbaustufe ein SubForm zu erzeugen und dieses zu schließen - letzteres entweder ausgelöst vom dazugehörigen ViewModel oder vom MainViewModel. Aber eben immer mit der Prämisse: Das ViewModel weiß nix vom View, daher muss man was dazwischenschalten, damit es egal ist, ob das ViewModel nun von einem WPF-Window oder einem WinForms-Form oder irgendeinem anderen UI verwendet wird. Nur der DialogService kennt die Fakten/Wahrheit/Details.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Durch das Tutorial von Nofear23m habe ich auch eine Weile "Service" im namen verwendet, scheint sich durch das Tutorial hier so eingebürgert zu haben. Aktuell verwende ich Benamungen mit Dependency und Contract. Denn das was Nofear23m in dem Tutorial zeigt, ist eine minimale Variante von Dependency-Injection. Daher sind Namen wie IDependencyContract, TDependencyContract oder IWindowDependencyContract IMO passender als wie was mit Service. Wenn ich an einen Service denke, denke ich eher an Windows-Services, also diese, die man im services.msc controlpanel starten und stoppen kann.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „DTF“ ()

    Contract - Vertrag?
    Nuja, das Teil macht ja irgendwas. Sollte sich der Name nicht daran orientieren? Ein Vertrag wär für mich fast schon ein Interface - oder vice versa.
    Vielleicht sollte man es auch einfach spezifisch so benennen wie die Aufgabe, die es erfüllt. Hier vielleicht ViewCreator. Obwohl es wohl zukünftig wohl mehr macht als nur erschaffen :/ . Manager sollte man wohl immer bei der Benennung meiden, weil jede Klasse irgendwas managt. @ErfinderDesRades: Bei Dir würde es wohl in die Kategorie Helper fallen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Contract - Vertrag?


    Ja genau! Das Basis-Interface heist bei mir IDependencyContract(siehe den ServiceContainer im Tutorial, im kapitel mit den services, daher erwähnte ich auch den namen mit beginnendem T). Dazu hab ich dann weitere Interfaces die dieses inne haben. Z.B. IMainWindowDependencyContract Dependency halt weil das eine kleine DI-Variante ist. Wobei vertragsbedingung noch passender wäre, man muss ja diese Interfaces implementieren, welche halt vorschreiben welche Funktionen/Methoden dann in der Klasse zu sein haben. So hat man Abhängigkeiten die Klasseninstanzen die das interface inne haben, und wie du auch schon sagtest Contract ist fast schon ein Interface.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „DTF“ ()

    Achso. Ich dachte, die Klasse heißt irgendwas mit Contract. Dass das Interface so genannt wird, lass ich mir einreden. Auch wenn ich das moppelt gedoppelt finde. Ein Interface ist für mich ja eine Art Vertrag, da brauch ich das nicht noch im Namen. Ich versuch es ja eher so zu halten, dass der Interfacename aussagt, was der Vertrag über den Implementierer aussagt - falls möglich. Klappt aber auch nicht immer. So z.B. ICloseable, aber eben auch IManagedShutdown.
    Aber gut, dann zur Kenntnis genommen: Ich hab's falsch verstanden. Nicht die Benennung der Klasse ist gemeint, sondern des Interfaces.
    Oder benennst Du die Klassen dann ähnlich dem zu implementierenden Interface?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    ErfinderDesRades schrieb:

    Server-Client-Netz-Architektur,


    Ich glaub das Trifft es schon gut. In MVVM bietet ein Service Dienste an, die von ViewModels angefordert werden können.
    Services in MVVM Entkopplt ViewModels und Views.
    ViewModel ist es egal wie der Service das macht,Will nur die View oder Window.
    Server entkoppelt Serverkomponete von Client.
    Client ist das auch egal

    Das hat bestimmt auch was mit der Projektmappe Struktur zu tun.
    In grösseren ProjektenMappen findet man oft eine [App].Services Projekt die Klassen beinhalten, die mit Service enden.


    Ein Manager kontrolliert und koordiniert mehr Daten und Ressourcen, während ein Service eher Funktionalität bietet,
    wie beenden des Dialogs in dem fall,den das ViewModel nicht kennt, aber von der View angefordert wird.
    Also meistens redet man von Service aber Manager sehe ich bei meinen recherchen auch hin und wieder.

    ErfinderDesRades schrieb:

    Einen Dielog von einem Service abrufen - das geht über meinen Horizont. Bei mir sind Dialoge Bestandteil der Client-Anwendung, und kann man keinesfalls iwo anders hin verfrachten, und dann abrufen.
    ein Dialog ist ja kein Datenpaket.




    Es wird kein Dialog aufgerufen nur die Eigenschaften des Dialogs die gebunden sind werden geändert. ?(

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Amro“ ()

    Ich hab mich für Service entschieden weil ich in WPF ein NavigationService gebaut hab
    was zwischen den Views(UserControls) die auf meine Window sind hin und her Navigiert.
    In dem Projekt kommt warscheinlich auch der DialogService rein wenn ich den irgend wann mal brauche
    Manager will ich aufheben für zum Beispiel FileManager oder ImageManger und so .
    Dinge die Daten betreffen und irgendwie verarbeitet werden müssen.
    Aber wichtig ist glaub ich das man da etwas trennt für sich selbst, weil mit der Zeit kommen immer mehr Projekte hinzu die irgenwelche Aufgaben erledigen. Und das man selber durchblickt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Amro“ ()