MVVM mit WinForms - kleiner Einstieg für Anfänger

    • VB.NET
    • .NET 7–8

      MVVM mit WinForms - kleiner Einstieg für Anfänger

      Hallo zusammen.

      WPF ist für mich immer noch ein Buch mit 7½ Siegeln. Es hat zwar mit dessen DataBinding-Mechanismen (besondern ausgeprägt in Form von MVVM) mein Interesse auf sich gezogen, durchgestiegen bin ich bei WPF aber bis heute nicht.
      Dank @loeffel und Co. ist es aber inzwischen auch möglich, ab .NET 7 MVVM mit WinForms zu kombinieren, siehe sein Artikel darüber. (Bei älteren .NET-Versionen standen mir die passenden Control-Properties nicht zur Verfügung)

      Was sich für mich endlich langsam rauskristallisiert (obwohl ich nur an der Oberfläche kratze):
      Dank des für WinForms neuen (aber für WPF schon wohl seit Anfang an vorhandenen) DataBinding-Mechanismus kann man z.B. das in eine andere Klasse auslagern, was passieren soll, wenn man einen Button anklickt.

      Würde man also klassisch in WinForms schreiben:

      VB.NET-Quellcode

      1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      2. 'hier die Aktion, die ausgeführt werden soll
      3. End Sub
      kann das mit dem neuen DataBinding-Mechanismus in die Zuständigkeit einer anderen Klasse fallen - und ist somit dem GUI/CodeBehind der Formklasse egal bis unbekannt! Es gibt dazu keinen Code mehr in der Formklasse.
      Das führt dazu, dass noch besser das zu Geschehene aus der Formklasse ausgelagert wird.

      Dazu baut man einen sogenannten RelayCommand ein, der über eine BindingSource an den Button und dessen Command-Property gebunden wird.
      Der RelayCommand ist eine selbstgebaute Klasse, die die ICommand-Schnittstelle implementiert. Den Code dafür hab ich aus dem oben genannten Artikel von @loeffel hergenommen und in VB.NET umgewandelt, wurde aber auch schon von @Nofear23m in seinem großen WPF-Tutorial verwendet.
      Dieser hat die Eigenschaften, dass er erstens die der Formklasse unbekannte Aktion auslöst, sobald der Button geklickt wird. Und zum anderen kann von außen gesteuert werden, ob der Button überhaupt angeklickt werden kann.

      Das einfache Projekt im Anhang soll zeigen, was damit gemeint ist.

      Klickt man den Button an, kommt eine MessageBox. Soweit nicht ungewöhnlich. Schaut man aber in die FrmMain.vb, sieht man, dass es keinen Button.Click-EventHandler gibt. Wo wird also die MessageBox aufgerufen? Dies geschieht in der Klasse Foo. Eine Instanz dieser Klasse steckt in der FooBindingSource auf dem Form. An deren Property RelayCommand ist die Button-Property Command gebunden.


      Wenn man jetzt den Button anklickt, wird die Aktion des RelayCommands ausgeführt. Diese ist aber innerhalb der RelayCommand-Klasse nicht konkret festgelegt. Sie wird durch die Foo-Instanz festgelegt. Es besteht also über dieses DataBinding eine Verbindung zwischen dem Button und der Foo-Instanz spezifischen RelayCommand-Instanz. Der Button meldet also nur, dass eine Aktion ausgeführt werden soll. Welche das ist, legt eine andere Klasse fest. Ganz ohne zusätzlichen EventHandler-Code in der Formklasse.

      kleiner Zusatz, der aber nicht sooo wichtig ist, da das früher auch schon durch klassisches DataBinding ging:

      Zusätzlich gibt es eine weitere Eigenschaft (besser: Funktion) der RelayCommand-Klasse: CanExecute. Sie legt fest, ob die Aktion überhaupt ausgeführt werden kann. Steht diese auf False, sorgt .NET bei einem Button dafür, dass dieser deaktiviert ist, man ihn also nicht anklicken kann. In Beispielprojekt ist dies durch die Foo-Property IsEnabled festgelegt. Wird diese auf False gestellt, wird die RelayCommand-Instanz explizit darüber informiert und diese meldet dem GUI, dass die RelayCommand-Aktion nicht ausgeführt werden kann, der Button also deaktiviert werden soll.

      Damit man das von außen testweise mal sieht, habe ich eine CheckBox mit klassischem DataBinding an die IsEnabled-Property der Foo-Instanz gebunden. Nimmt man das Häkchen raus, wird der Button ohne zusätzlichen Code deaktiviert. Das ging natürlich auch schon früher, indem die Button-Property Enabled an die entsprechende Foo-Property gebunden wurde. Aber das fällt jetzt eben auch weg.



      ##########

      Fragen oder Anmerkungen bitte an folgender Stelle posten: Diskussionsthread: MVVM mit WinForms - kleiner Einstieg für Anfänger
      Dateien
      • WinFormsNetVB.zip

        (13,66 kB, 175 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.

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