MVVM Umsetzung mit WinForms

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

Es gibt 163 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Also das mit dem "MVVM" habe ich verstanden, das dabei alles strickt getrennt wird.
    Irgendwo macht es aj auch Sinn, das zu trennen.

    Bzgl, bestimmte Controls / Bindngs usw auf das From ziehen usw.. kann man ja immer wieder in so vielen YT-Tutorials sehen. Ich glaube habe mich davon zu lange auf den falschen Pfad führen lassen.
    Jetzt umstellen ist nicht leicht, aber ich bin dabei ;)

    Fragen werden kommen :thumbsup:
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Also entweder bin ich zu blöd oder ....

    Ich bekomme es nicht hin, das eine "Sub Main" als Start genommen wird.
    Entweder wird mir das bei der Auswahl gar nicht angezeigt, oder es springt immer wieder auf "FrmMain" oder ich bekomme einen Fehler das es schon eine SubMain gibt und es Konflikte gibt.
    Könnt grad alles.... :cursing: :cursing:
    Bilder
    • fehler-1.jpg

      362,83 kB, 1.245×492, 27 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    Das ist leider auch noch ein bereits gemeldeter Fehler in .NET.
    Du musst leider manuell die vbproj-Datei ändern. Mit folgenden Sachen sollte die Datei beginnen:

    XML-Quellcode

    1. <Project Sdk="Microsoft.NET.Sdk">
    2. <PropertyGroup>
    3. <StartupObject>Sub Main</StartupObject>
    4. <UseWindowsForms>True</UseWindowsForms>
    5. <DisableImplicitNamespaceImports>true</DisableImplicitNamespaceImports>
    6. <OptionStrict>On</OptionStrict>


    Wenn es damit immer noch nicht klappt, lad das Testprojekt mal hoch und wir schauen mal, woran es liegt.
    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“ ()

    Moin moin

    Also das mit dem "Option Strict auf ON" ist auch so eine Sache. Habe es immer in den Einstellungen des Studios gemacht. In VS 2019 und 2022 muss ich aber trotzdem das nochmal explizit in den Projekteigenschaften machen.

    @VaporiZed
    Nachdem ich die Datei geändert hatte, startet VS2022 mit Fehlern..
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    Noch etwas was ich nach langem suchen endlich herraus gefunden habe, warum mein TestCode nicht funktionierte.

    Noch in VS 2017 und VS 2019 funktionierte die Version 1 ohne Probleme.

    In VS 2022 bekomme ich laufend Fehler die ich erst nicht ausfindig machen konnte. Habe X-Mal den TestCode neu gemacht. :cursing:
    Das blöde dabei ist, das es vom Studio erst als Fehler angemeckert wird, wenn man den Code ausführen möchte. <X

    Version 1:

    VB.NET-Quellcode

    1. Public Class DateManager
    2. Public Shared ReadOnly Instance As New DateManager()
    3. Public CurDatum As Date = Date.Today
    4. Public Sub MoveToPreviousMonth()
    5. CurDatum = CurDatum.AddMonths(-1)
    6. End Sub
    7. Public Sub MoveToNextMonth()
    8. CurDatum = CurDatum.AddMonths(1)
    9. End Sub
    10. End Class


    Version 2:

    VB.NET-Quellcode

    1. Public Class DateManager
    2. Private Shared ReadOnly _instance As New DateManager()
    3. Public Shared ReadOnly Property Instance As DateManager
    4. Get
    5. Return _instance
    6. End Get
    7. End Property
    8. Public CurDatum As Date = Date.Today
    9. Public Sub MoveToPreviousMonth()
    10. CurDatum = CurDatum.AddMonths(-1)
    11. End Sub
    12. Public Sub MoveToNextMonth()
    13. CurDatum = CurDatum.AddMonths(1)
    14. End Sub
    15. End Class
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Tja, in Version1 ist Instance ein Feld, in Version2 ists ein Property.
    Databinding geht nur mit Properties (falls das mit dem Problem zu tun hat).

    probier auchma

    VB.NET-Quellcode

    1. Public Class DateManager
    2. Public Shared ReadOnly Property Instance As New DateManager()
    3. Public CurDatum As Date = Date.Today
    4. Public Sub MoveToPreviousMonth()
    5. CurDatum = CurDatum.AddMonths(-1)
    6. End Sub
    7. Public Sub MoveToNextMonth()
    8. CurDatum = CurDatum.AddMonths(1)
    9. End Sub
    10. End Class

    Keine Ahnung, was Du mit der Projektvorlage gemacht hast, aber ich habe ein neues Projekt angelegt und jetzt klappt Dein Code - fast.
    Der eine Fehler im Startmodul aus Post#42 lag daran, dass in FrmMain die BS »BsDateViewModel« heißt, obwohl sie »BsDataViewModel« richtig heißt. Klassischer Schreibfehler, was der Compiler zurecht nicht ausgleichen kann.
    Für den Start fehlt auch noch Dein IClimaDatasRepository-Interface und ein dies implementierendes Objekt. Sonst kann der Konstruktor nicht aufgerufen werden:

    VB.NET-Quellcode

    1. Public Class DataViewModel
    2. '[…]
    3. Public Sub New(repository As IClimaDatasRepository)
    4. _repository = repository
    5. End Sub
    6. End Class
    Dateien
    • Meteo XT.zip

      (7,08 kB, 24 mal heruntergeladen, zuletzt: )
    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
    Moin moin

    Danke für deine Arbeit.
    Sobald ich auf "Bereinigen und neu erstellen" gehe, bekomme ich wieder den Fehler:

    Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    Fehler (aktiv) BC30738 '"Sub Main" wird in "MeteorosXT" mehrmals deklariert: MeteorosXT.My.MyApplication.Main(Args As String()), MeteorosXT.Main.Main() MeteorosXT C:\Users\Nyxalor\Entwicklungen\MeteorosXT\vbc 1

    Dann soll es wohl nicht funktionieren. ;(
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Kann ich nicht nachvollziehen. Jemand anderes der Mitleser? Aber lad mal hoch, was Du jetzt hast, denn bei mir kommt nur, dass das IClimaDatasRepository-Interface nicht deklariert ist. Wenn Du das hast, wer weiß, was Du noch alles hast.
    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:

    Jemand anderes der Mitleser? ... bei mir kommt nur, dass das IClimaDatasRepository-Interface nicht deklariert ist
    Same

    Aber heißt auch Meteo XT und nicht MeteorosXT wie im Fehler geschrieben, der Name wird sich doch wohl nicht beim Runterladen ändern?
    Also in MeteorosXT ist bei mir folglich garnix deklariert, weils das nicht gibt.
    Hallo

    Ich habe nochmal versucht, das selber so hinzubekommen wie @VaporiZed in dem Beispiel gezeigt hat. Deswegen der etwas andere Name. SORRY für die Verwirrung!

    Ich habe ein ganz neues Projekt begonnen und nur die benötigten Classen ( wie im Beispiel ) erstellt und dann die Modifikation in der vbproj gemacht. Ganz ohne das Interface Zeugs!!
    Schon dabei kommen die Fehler, wenn ich dann das Projekt neu lade.

    Ich habe nun einen Anfang eines Workaround für die Sache. Ich habe das "Model", das "ViewModel" und das "View"; zwar etwas Code auf dem View aber nur noch wenige zeilen.
    Das mit dem habe ich noch nicht ganz verstanden wie das geht:

    VB.NET-Quellcode

    1. Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    2. Protected Sub OnPropertyChanged(<CallerMemberName> Optional propertyName As String = Nothing)
    3. RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    4. End Sub


    Muss da noch bissel tüfteln lesen und hoffen zu verstehen...


    EDIT: 19:40 Uhr
    Ich versuche gerade herraus zuarbeiten, wann welche Class wo ins "MVVM" Prinzip gehört. Garnicht so einfach!
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    Amelie schrieb:

    Das mit dem habe ich noch nicht ganz verstanden wie das geht:
    Die Sub OnPropertyChanged wird im Setter einer Property explizit aufgerufen, und sie löst das Ereignis PropertyChanged aus, damit die BindingSources bzw das GUI informiert werden. Allerdings will die BS auch wissen, welche Property geändert wurde, damit sie das spezifische Binding nutzen kann, um die betroffenen Controls zu aktualisieren und nicht alle Controls, die über sie gebunden sind. Man muss also immer den Namen der Property im Setter an die Sub OnPropertyChanged mit übergeben. Allerdingss hat Microsoft irgendwann den Trick mit dem CallerMemberName-Attribut hinzugefügt, damit man eben nicht mehr explizit den Namen übergeben muss, sondern der Name wird von der aufrufenden Property autopmatisch mit übertragen -> einfacherer Code.

    Amelie schrieb:

    Ich versuche gerade herraus zuarbeiten, wann welche Class wo ins "MVVM" Prinzip gehört.
    Wozu? GUI/Form = View, ViewModel = Klasse mit Propertys, an das das GUI/die BS bindet. Der große Rest meist Model.
    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.
    Tatsächlich braucht man dieses Event nicht, zumindest in WPF, ich glaube als ich mich danach erkundigt habe kam es auf n Spezialfall raus. Die Bindings reagieren an sich schon auf die geänderte Property
    Habe dann aber rausgefunden, dass man damit andere Properties anstupsen kann. Also:

    VB.NET-Quellcode

    1. Public Property FilterXY As String
    2. Get
    3. Return _FilterXY
    4. End Get
    5. Set
    6. _FilterXY = Value
    7. _cvDings.Filter = Function(x) FilterDings(DirectCast(x, Dings))
    8. RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(AndereProperty)))
    9. End Set
    10. End Property
    11. Public ReadOnly Property AndereProperty As String
    12. Get
    13. Return $"Foo{IrgendwasDassSichMöglicherweiseMitmFilterGeändertHat}"
    14. End Get
    15. End Property
    Also der User setzt n Filter, das ändert an sich schon was ohne Event. Aber außerdem wird ne andere Property aktualisiert, die sich sonst nicht ändern würde.

    Wäre interessant zu wissen obs in WinForms dagegen tatsächlich erforderlich is für die Property die tatsächlich aktualisiert wurde. Weil sowas hab ich anfangs gedacht.

    Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    @ErfinderDesRades
    Da bin ich aber auf der einen Seite "froh". :D Dachte schon ich bin echt .....

    @VaporiZed
    Ich habe nun mal ein älteres kleines Projekt von mir genommen und versucht nach "MVVM" umzusetzen.
    Im FrmMain ist nur ein TestButton der den Logger testet.

    Was ich so richtig umgesetzt habe ist das "Setting". Es funktionier aber hat doch meine Hirnzellen fast zum glühen gebracht, wegen des ganzen umdenkens... <X

    Ich hoffe ich bin da auf dem "richtigen" Weg :?:
    Zipfile ist bereinigt!
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    Habt Ihr schon diesen stackoverflow-Post#1 gelesen und probiert? Klappt es vielleicht damit?

    @Amelie: Naja, nee, eigentlich nicht. Ich könnte es ja noch akzeptieren, wenn Du die Button-EventHandlers in dem .NET-Framework (».NET-FX«) Projekt behältst, weil .NET-FX noch keine Command-Property für den Button bereit stellt. Aber sonst sollte im CodeBehind der Forms gar nix stehen. Der Einstiegspunkt bei nem MVVM sollte m.E. nie ein Form sein.
    Die BindControls-Sub in FrmSettings versteh ich gar nicht. Warum machst Du das nicht im Designer?
    Der Timer könnte auch ersetzt werden. Soll sich doch das VM nebenläufig darum selber kümmern.
    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“ ()

    Der Anfangsblock enthält ja auch das Relevante:
    Solved this issue and posting to help future readers.
    Da steht drin, wie der User es lösen konnte.
    After experimenting with many different ways of correcting the issue, I ultimately resolved it by accessing the project's properties (My Project) area -> Application -> Check the box Use Application Framework. This will change the startup object to a form. Now uncheck the Use Application Framework box and select your Sub Main which you've already created.

    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.
    Moin moin

    Also nach dem Post in stackoverflow habe ich es hinbekommen. :)
    Da die Debugausgabe erscheint, gehe ich mal davon aus, das auch die "Sub Main" gestartet wird.

    VB.NET-Quellcode

    1. Module StartMain
    2. Sub Main()
    3. Application.EnableVisualStyles()
    4. Debug.WriteLine($"In der Sub Main")
    5. Using Dialog As New FrmMain
    6. Dialog.ShowDialog()
    7. End Using
    8. End Sub
    9. End Module


    In der .vbproj

    VB.NET-Quellcode

    1. <PropertyGroup>
    2. <OutputType>WinExe</OutputType>
    3. <TargetFramework>net7.0-windows</TargetFramework>
    4. <StartupObject>Sub Main</StartupObject>
    5. <UseWindowsForms>True</UseWindowsForms>
    6. <MyType>WindowsFormsWithCustomSubMain</MyType>
    7. </PropertyGroup>

    Nur das: Use Application Framework zu finden war garnicht so einfach. Im alten Studio war das viel übersichtlicher. In 2022 übersieht man so einiges.

    Wieder etwas, was in meinem Kopf nicht passt. Warum muss man immer etwas so stark verändern das man wieder ewigkeiten braucht um alles zu finden???
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh: