MVVM Umsetzung mit WinForms

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

Es gibt 194 Antworten in diesem Thema. Der letzte Beitrag () ist von Amelie.

    @VaporiZed

    Erstmal Danke für die Erklärungen und das Übungsprojekt.

    Leider bekomme ich da Fehler. Siehe Bilder

    Habe ganz frisch das .Net nachinstalliert usw...
    Bilder
    • mvvmerror1.jpg

      261,79 kB, 1.136×643, 53 mal angesehen
    • mvvmerror2.jpg

      263,18 kB, 1.213×450, 38 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    @Amelie

    Versuch einfach ein adneres Framework einzustellen. Im Projektmappenexplorer rechtklick auf das Projekt(das mit dem VB Icon in der Mappe), dort dann auf Eigenschaften klicken. Schau dann nach "Zielframework" und stell da was ein. Kannst natürlich mit einem Doppelklick die Datei öffnen, dort musst du aber selbst den Text bearbeiten. Im Zweifel die UI nutzen an die du wie gesagt kommst.
    Bilder
    • Unbenannt.jpg

      63,64 kB, 851×219, 44 mal angesehen
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D
    Welches Studio?
    Wenn du ein neues Projekt anlegst, kannst du denn da NET auswählen? Dazu musst du aber ein NET Projekt auswählen kein NET-Framework.
    Wenn du kein NET(ohne Framework) ProjektTemplate findest, ist dein Studio evtl. zu alt.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D
    Moin moin
    Zur Zeit habe ich VS 2017. Ich hatte erst VS 2019 auf dem neuen Windows 10 aber da hatte ich Probleme.
    Unter anderem konnte ich keine eigenen Usercontrols auf die Form ziehen.
    Der selbe Code des UserControls in VS2017 funktionierte.


    Und wie es scheint, kann VS2017 wohl nur .Net Consolen Anwendungen.???
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Und wie es scheint, kann VS2017 wohl nur .Net Consolen Anwendungen
    Quatsch.
    Das hast du sicher die falsche Einstellung erwischt.
    Es gibt z.B. die Projektvorlage Windows-Forms-App (.NET Framework).

    Oder du hast dein Studio so kastriert installiert, dass alles abgewählt wurde.
    Dann starte den Visual Studio Installer und lade den gewünschten Rest nach.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

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

    Amelie schrieb:

    Unter anderem konnte ich keine eigenen Usercontrols auf die Form ziehen.


    Installier dir einfach mal das aktuelle Studio -> Visual Studio Community 2022, da funktioniert das mit den Usercontrols. Ich versteh nicht warum du immer noch an den alten Studios festhälst. Fehlt was, startest du den "Installer", da kannste dann alles was du brauchst installieren, auch im Nachhinein.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D
    Hallo zusammen.

    Habe das Paket was @ErfinderDesRades genannt hatte schon installiert. Allerdings net.8

    Das VS habe ich nachgesehen und so ziemlich alles installiert was ich so brauche. Das android zeugs usw ...nicht.
    Im Bild ist zu sehen, was ich bei .Net zur Auswahl habe. Bei C# fast identisch.

    Vielleicht mal das Studio komplett installieren?
    Bilder
    • netcor1.jpg

      328,45 kB, 1.065×684, 40 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    .NET Core (das ist .NET bis 3.1, Du brauchst mindestens 7.0) ist genauso falsch wie .NET Standard. Schau mal bei Windows Desktop rein, vielleicht ist es dort.
    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.
    Hallo
    Bin gerade dabei das VS 2022 zu installieren. Dauert ein wenig.

    Obwohl ich .Net 8 installiert hatte war VS2017 nicht dazu zu bewegen etwas derartiges zu zeigen. ;(
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    Dein Bild enthält persönliche Daten. Entfern es lieber, wir glauben Dir auch so, dass Du VS22 installierst.
    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

    Ich habe mal mit deinem Mini Beispiel-Projekt etwas probiert.

    Ich bekomme zwar eine Combobox mit dem Binding hin, aber folgendes:
    Ich sehe im Desinger bei der Auswahl das Binding mit Drives. Wähle ich das aus wird eine weitere Binding: "DrivesBindingSource" erstellt.

    Diese neue hat dann das DataSource ==> "BsViewModel" ==> DataMember "Drives"

    Das kommt mir so "doppeltgemoppelt" vor???

    Aufjedenfall, muss ich da sehr viel umdenken, weil alles so anders ist..
    Bilder
    • comboBindings1.jpg

      120,95 kB, 420×441, 39 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    Amelie schrieb:

    Aufjedenfall, muss ich da sehr viel umdenken, weil alles so anders ist..
    Wie geschrieben, fast alles wäre mit .NET-Framework auch schon möglich gewesen. Dass Du bisher DataBinding noch nicht so genutzt hast, liegt schonmal nicht an .NET. Sondern wahrscheinlich eher daran, dass Du den Thread WinForms Projektentwicklung bzgl. der Rolle des Formulars vielleicht gelesen, aber womöglich noch nicht die einzelnen Stufenprojekte ausprobiert und nachvollzogen hattest ;)
    Aber macht nix. Dann eben jetzt.

    Anbei die Korrektur.

    Amelie schrieb:

    Das kommt mir so "doppeltgemoppelt" vor???
    Das ist aber tatsächlich notwendig. Für ein korrektes DataBinding benötigen Auflistungen eine eigene BindingSource (BS). Allein schon für die BS-Eigenschaften Current und Position. Wie sonst sollte eine Property, die aus mehreren Einträgen besteht (Drives als ObservableCollection) so abgebildet werden, dass der ausgewählte Wert nachvollziehbar ist?
    Weil ich grad beim Thema bin: Ich habe bei der ComboBox noch die Eigenschaft ausgewählter Wert festgelegt. Das erspart Dir den Code, dem Du im MainForm-CodeBehind hattest. Da soll nämlich gar nix stehen ;)
    Das Ärgerliche, was ich auch nochmal @loeffel schreiben werde: Der Designer unterstützt bisher keine Direktauswahl der DataBinding-Eigenschaften, ich musste es in die FrmMain.Designer.vb manuell eintragen :thumbdown:

    Ansonsten habe ich die VmMain.vb noch etwas gekürzt, weil Du die ausführliche Schreibweise der Propertys nicht brauchst. Die einzeilige AutoProperty-Schreibweise reicht, solange Du nix spezielles in den Gettern/Settern machst.
    Dateien
    • MVVM Übung.zip

      (83,6 kB, 93 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

    Habe mich nun mal fast den ganzen tag damit beschäftigt.
    Ist schon eine große Umstellung und viel hinundher wenn so garnix mehr in der Form-Class an Code ist.
    Das schwierigste ist z.B. Contorls zu "formatieren" usw....

    Public Class RelayCommand
    Was die Class so bewirkt ... hmmm noch ein Buch mit 7 ...nee 77 Sieglen :D
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Ich schrieb ja. Nimm sie zur Kenntnis, aber anfänglich solltest Du sie ignorieren. Aber bitte: Die RelayCommand-Klasse ist eine allgemeine Klasse, die das ICommand-Interface implementiert. Damit wird sie für das Button-DataBinding an die Command-Property zugänglich. Eine VmMain-Property, die eine RelayCommand-Klasseninstanz ist, kann also an die Command-Property eines Button gebunden werden. Klar soweit? Also DataBinding geht grundsätzlich nur mit Propertys P und das DataBinding an die Button-Command-Property geht zusätzlich nur, wenn die Property P das ICommand-Interface implementiert. Da im Code steht Property Blablabla As New RelayCommand, sind beide Bedingungen erfüllt: Property und ICommand-Implementierung.

    Was die RelayCommand-Klasse jetzt macht: Dem Konstruktor gibt man die Adresse einer Methode, die dann ausgeführt werden soll, wenn die Execute-Methode des RelayCommands aufgerufen wird. Wann passiert das? Wenn der RelayCommand an einen Button gebunden ist und der Button geklickt wird. Also quasi: »Ich erstelle mir eine VmMain-Property SaveDataRelayCommand vom Typ RelayCommand. Diese Property soll sich mal die Aktion SaveData merken. Wenn der Button, an den ich SaveDataRelayCommand binde, geklickt wird, kümmert sich .NET darum, dass dann automatisch die hinterlegte Aktion SaveData aufgerufen wird.«

    Belassen wir es erstmal dabei. Wenn das sitzt, können wir uns um den Rest der Klasse kümmern. Dein Hauptaugenmerk sollte darin liegen, das Form codefrei zu halten und all Deinen Code in der VmMain-Klasse zu belassen.
    Der spätere Schritt ist natürlich, dass die VmMain-Klasse (ist ja das ViewModel) nicht alles weiß, sondern dass die Modelklassen hinzukommen. Das ViewModel vermittelt ja nur zwischen GUI/View und Modelklassen.

    ##########

    Was meinst Du mit »Controls formatieren«? Das DataBinding einzurichten?
    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“ ()

    @VaporiZed

    Moin moin

    ​Was meinst Du mit »Controls formatieren«?

    Soetwas z.B.: Die Textbox ist ja auf dem Form. Da fehlt mir der Ansatz, wie das nun in die VmMain kommt.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub LastCalibration_Leave(sender As Object, e As EventArgs) Handles LastCalibration.Leave
    2. Dim dateString As String = LastCalibration.Text.Trim()
    3. ' Überprüfen, ob das Datum im richtigen Format ist
    4. If Not IsDate(dateString) Then
    5. MessageBox.Show("Ungültiges Datumsformat. Bitte geben Sie das Datum im Format TT.MM.JJJJ ein.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
    6. LastCalibration.Focus() ' Fokus auf das Textfeld setzen, damit der Benutzer es erneut bearbeiten kann
    7. End If
    8. End Sub



    -------------------------
    Naja und wie ich glaube schon erwähnte, bekommt man gefühlt nun noch mehr Code. Frage mich ob das wirklich bei jedem Projekt Sinn macht?
    Und als nächstes, das mit den Bindings.
    Habe also nun haufen Bindings zwischen der GUI und dem ViewModel. Nun kommen ja noch die Bindings zwischen den eigentlichen Daten / Einstellungen dazu.
    Beispiel:

    Für Programmeinstellungen usw...
    Dataset: dsAppsettings
    Datatable: Stationen und Adjustment und Settings

    dann
    Die eigentlichen Messdaten
    DataSet: dsClimaValues
    DataTable: Messwerte

    dafür auch jeweils eine Bindingsource gemacht. diese muss ja nun auch an die " VmModel-Class " dran :?: ( Überlegung ob alle DataTables in ein DataSet ?( )

    Dann kommen ja noch die ganzen Sachen, zum Beispiel für das Blättern ( Monat vor / zurück ) dafür die Logik usw.... wenn ein neuer Monat beginnt ein neues "Sheet" erstellen usw... ggf Fehler abfangen, Validierungen der Eingaben im DGV ... ppüüüüühhh <X <X


    Manchmal Frage ich mich, wenn ich das DataSet / DataTables alles im Designer erstellt habe:
    Wann ziehe ich z.B. ein DGV nicht einfach aus den "Datenquellen" auf das Form, mache den 2-Zeiler zum speichern. Ein paar Subs zum formatieren, Fehler abfangen und Validierung und gut ist.

    Das Programm läuft. "yeeaaar"
    Klar, ich habe keine Ahnung was dann da im Hintergrund passiert. Naja .. viel Fragen und Unsicherheiten schwirren durch mein Kopf. :(

    Zumindest habe ich nun erstmal die Classes soweit am laufen, das ich die Daten aus den XML-Files in die ==> DS/DT ==> Bindingsource bekomme.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Die Textbox ist ja auf dem Form. Da fehlt mir der Ansatz, wie das nun in die VmMain kommt.
    Die TextBox gar nicht. Was Du in VmMain haben wirst und willst: Den Text der TextBox. Du erstellst Dir ne String-Property im VmMain und bindest im Designer die TextProperty der TextBox an die String-Property. Fertig. Den Leave-EventHandler brauchst Du nicht. Denn was passiert in dem EventHadler bisher? »Wenn die TextBox verlassen wird, prüfe die Daten.« Und da sind wir bei dem, was ich in Post#20 geschrieben habe. Wenn die Daten einer TextBox überprüft werden sollen, wenn sie verlassen und damit validiert werden, muss das Binding nicht extra verändert werden, da das StandardBinding besagt: »aktualisiere die DataBinding-Property OnValidation«. Das bedeutet: Wenn eine Validierung durchgeführt der TextBox-TextProperty durchgeführt wird (nämlich beim Verlassen der TextBox), dann erst aktualisiert .NET die String-Property in VmMain. Und wie kannst Du jetzt die eingegebenen Daten in VmMain prüfen? Indem Du die Datenprüfung im Setter der gebundenen String-Property machst. Also gibt es nicht mehr Code zu schreiben als bisher, sondern es ist nur eine Verschiebung von Form-CodeBehind nach VmMain.
    rudimentäres Beispiel innerhalb von VmMain:

    VB.NET-Quellcode

    1. Private _CalibrationDateText As String
    2. Property CalibrationDateText As String
    3. Get
    4. Return _CalibrationDateText As String
    5. End Get
    6. Set
    7. If Not Date.TryParse(Value.Trim) Then MessageBox.Show("ungültiges Datumsformat."): Return
    8. _CalibrationDateText = Value
    9. End Set


    Zum Rest schreib ich später noch was.

    ##########

    Amelie schrieb:

    Naja und wie ich glaube schon erwähnte, bekommt man gefühlt nun noch mehr Code. Frage mich ob das wirklich bei jedem Projekt Sinn macht?
    Das ist immer die Frage. Wenn Du ein Programm hast, was auf eine Bildschirmseite passt, wäre es nicht sinnvoll, MVVM anzuwenden. Je größer das Projekt, dest mehr ergibt es Sinn, mithilfe von MVVM oder anderen Strukturdesignpatterns das Programm auzuteilen bzw. zu gestalten, um u.a. die Übersicht zu behalten. Wenn Du alles in die Formklasse packst (Stichwort Klumpenform/Monolith), dann ist das zwar alles in einer Datei. Aber Du hast ggf. 50000 Codezeilen. Das wird's übel mit der Übersicht. Aber ja, je mehr Klassen beteiligt sind, desto mehr müssen die auch miteinander kommunizieren. Aber das ist ja auch OOP.

    DataSet und MVVM gehen bei mir nicht zusammen. Entweder tDS oder MVVM. Ja, richtig gelesen.

    Blättern von Daten? Ich versteh nicht, wo das Problem ist. Dass die Daten quasi gefiltert werden? In VmMain sind die Daten verfügbar. Und wenn das GUI sagt: Ich brauch andere Daten, weil der User jetzt nen anderen Monat sehen will, geht der Befehl an VmMain und VmMain kümmert sich darum, dass die gewüschten Daten dem GUI zur Verfügung gestellt werden. So läuft das immer: User verwendet GUI, GUI meldet Wünsche ans ViewModel, ViewModel meldet die gewünschten Daten ans GUI, GUI stellt die Daten dar. Das ist das Grundprinzip von MVVM.

    Amelie schrieb:

    Wann ziehe ich z.B. ein DGV nicht einfach aus den "Datenquellen" auf das Form, mache den 2-Zeiler zum speichern. Ein paar Subs zum formatieren, Fehler abfangen und Validierung und gut ist.
    Tschuldigung, aber Du wolltest MVVM kennenlernen. Wenn doch wieder das GUI Aufgaben übernehmen soll, die nicht zum Aufgabenbereich des GUIs gehören (und genau das ist der springende Punkt!), dann hat das nix mehr mit MVVM zu tun. Das GUI hat die Aufgabe, Daten darzustellen und Benutzereingaben weiterzugeben. Sonst gar nix. Dass man es vor allem als Programmieranfänger (ich zähl Dich nicht mehr dazu) so macht, dass das Form alles kann/macht/weiß, ist der Anfang vom Ende eines komplexen Projektes. Stichwort Spaghetticode.
    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 3 mal editiert, zuletzt von „VaporiZed“ ()