Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

11

17.02.2016, 15:27

Wenn Model B von Model A abhängig ist, dann wird im Setter von A die onPropertyChange Methode halt für beide aufgerufen.
Dann müssen meine Models also auch INotifyPropertyChanged implementieren?

Weißt du, ich habe noch immer ein Problem damit, dass ich meine bisherigen Models nun in ein ViewModel und ein Model autrennen muss. Ich habe das jetzt so verstanden, dass ein Model zwingend ein ViewModel braucht, wenn es verändert werden soll. Also bringt es den Models doch rein garnichts, wenn sie sich gegenseitig kennen - sie benötigen für alles was sie mit dem anderen machen wollen das zugehörige ViewModel. Selbst wenn ein Model sich selbst (mit der Zeit) verändern soll, darf es die Änderungen nicht an sich selbst durchführen, sondern muss die gewünschten Änderungen alle an sein ViewModel weiterleiten, damit dieses nun die Änderungen am Model durchführt. Da würde ich mir ja glatt sagen: Du schreibst überhaupt keine Methoden mehr im Model, sondern schreibst alles im ViewModel - das Model ist nur noch der Speicher für die Variablen. Ist das denn so gewollt?
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

12

17.02.2016, 16:20

Also bringt es den Models doch rein garnichts, wenn sie sich gegenseitig kennen - sie benötigen für alles was sie mit dem anderen machen wollen das zugehörige ViewModel.
Dann hast Du das Konzept noch immer nicht verstanden. Modelle sind völlig unabhängig von ViewModels. Deine gesamte interne Logik sollte auch komplett ohne ViewModels oder Views funktionieren. Sie kennen sich also schon untereinander und agieren miteinander (wenn auch bitte niemals im Zyklus). Das dürfen und sollen sie auch ganz direkt machen.
Willst Du aber die Werte von Models über eine GUI durch einen Benutzer veränderbar machen, dann läuft diese Veränderung immer über ViewModels. Stell es Dir einfach so vor, dass Du in der Lage sein willst die Models auch mit einer komplett anderen GUI (oder gar keiner!) benutzen zu können. Folglich wäre es also fatal, wenn Models und ViewModels zusammengepanscht sind. Andererseits soll es auch möglich sein die Struktur des Models ändern zu können, ohne bei jedem Bisschen die kompletten Views umbauen zu müssen. Solange das ViewModel zwischen beiden vermitteln kann, ist alles gut und richtig.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »BlueCobold« (17.02.2016, 16:26)


CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

13

17.02.2016, 18:53

(wenn auch bitte niemals im Zyklus)
Nein klar, das passiert auch nicht. ;)

Das dürfen und sollen sie auch ganz direkt machen
Ok, das bekomme ich hin. Aber wie bitteschön wird dann die View geupdated? Ich zeige nämlich auch Werte an, die der User nur angucken kann - aber die werden laufend von den Models geändert. Muss mein Model dann INPC implementieren?

Andererseits soll es auch möglich sein die Struktur des Models ändern zu können, ohne bei jedem Bisschen die kompletten Views umbauen zu müssen.
Das habe ich bisher auch so gemacht - soweit kommts noch, dass ich ständig meine Views anpassen muss. ;) Dieses Prinzip von MVVM habe ich verstanden!
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

14

17.02.2016, 21:36

Die View wird dann geupdatet wenn das PropertyChanged-Event des zugehörigen ViewModels getriggert wird.
Ich verstehe auch nicht wieso du immer wieder sagst du musst dazu das INotifyPropertyChanged- Interface
in den Models implementieren.

Normal haben nur die ViewModels dieses Interface implementiert. Vom Ablauf her sieht das Ganze dann so aus
... sobald eine View ein ViewModel als DataContext zugewiesen bekommt, abbonniert die View automatisch das
PropertyChanged Event. Sobald dieses auslöst überprüft die View ob ein DataBindung zu der Variable vorliegt
(deshalb übergibst du den Namen der Property beim Auslösen des Events), wenn ja updatet die View den Wert
indem sie den Getter der entsprechenden Property aufruft.

Möchtest du das Werte nur angezeigt werden so hast du verschiedene Optionen. Entweder du nimmst gleich einen TextBlock,
da dieser gar nicht erst editiert werden kann oder du gibst beim Binding den Mode mit Mode=OneWay an. Was bedeutet
dass der Wert nur abgerufen werden kann, aber nicht editiert.
Die Set-Methode einfach auf privat setzen könnte auch gehen, ist aber sicher keine schöne Lösung und könnte zu unschönen
Bugs führen.

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

15

17.02.2016, 22:16

Normal haben nur die ViewModels dieses Interface implementiert. Vom Ablauf her sieht das Ganze dann so aus
... sobald eine View ein ViewModel als DataContext zugewiesen bekommt, abbonniert die View automatisch das
PropertyChanged Event. Sobald dieses auslöst überprüft die View ob ein DataBindung zu der Variable vorliegt
(deshalb übergibst du den Namen der Property beim Auslösen des Events), wenn ja updatet die View den Wert
indem sie den Getter der entsprechenden Property aufruft.

Möchtest du das Werte nur angezeigt werden so hast du verschiedene Optionen. Entweder du nimmst gleich einen TextBlock,
da dieser gar nicht erst editiert werden kann oder du gibst beim Binding den Mode mit Mode=OneWay an. Was bedeutet
dass der Wert nur abgerufen werden kann, aber nicht editiert.
Die Set-Methode einfach auf privat setzen könnte auch gehen, ist aber sicher keine schöne Lösung und könnte zu unschönen
Bugs führen.
Diese Prinzipien kenne ich schon - hast du gut zusammengefasst. :) Mein Problem ist beim ViewModel und beim Model - mit der View komme ich klar. Ich versuche es nochmal mit einem Beispiel:

Ich habe zwei Klassen: InputPin und OutputPin. Die Geräte haben beispielsweise mehrere InputPins, weil sie Werte (Farbe, Helligkeit, etc.) bekommen, die dann das Gerät drehen und leuchten lassen. Außerdem gibt es verschiedene Effekte, die haben OutputPins, die man mit beliebigen InputPins verknüpfen kann. Die Effekte verändern die Werte ihrer OutputPins (nach Zeit oder so), diese wiederum sind mit irgendwelchen InputPins verknüpft, die sofort den neuen Wert mitgeteilt bekommen. Wenn ein OutputPin mit einem InputPin verknüpft wird, dann bekommt der OutputPin einfach eine Referenz vom InputPin, die er speichert. Der InputPin hat eine Property namens Value - die wird vom OutputPin gesetzt. Soweit zur vereinfachten Funktionsweise meines Lichtprogramms.

In meiner GUI möchte ich gerne die Werte, die ein OutputPin und ein InputPin haben, Live angezeigt bekommen (readonly). Nach MVVM sind also die beiden Klassen InputPin und OutputPin Models. BlueCobold hat in seiner letzten Antwort
Deine gesamte interne Logik sollte auch komplett ohne ViewModels oder Views funktionieren. Sie kennen sich also schon untereinander und agieren miteinander (wenn auch bitte niemals im Zyklus). Das dürfen und sollen sie auch ganz direkt machen.
geschrieben, dass die Models untereinander kommunizieren dürfen - das ist ja bei meinem Beispiel der Fall.

Nun ist meine Frage, wie denn die View und das ViewModel von den Änderungen der Value Property etwas mitbekommen sollen. Ist meine Aussage bezüglich INPC jetzt besser zu verstehen?
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

16

18.02.2016, 10:40

Hallo, ich geb mal meine 2 Cent dazu.

Dein Modell (nicht Viewmodel) enthält ja die Logik deiner Anwendung.

Also angenommen, du willst statt einer UI ein Interface für ein Gerät anbinden, dann muss deine Anwendungslogik genauso das Interface darüber informieren, wenn ein Effekt einen Wert verändert hat.
Demnach würdest du also bei Veränderung des Wertes im OutputPin ein Event auslösen, welches du in der Geräteschnittstelle abfangen und weiterverarbeiten kannst.

So weit, so gut - du willst das jetzt auf der UI anzeigen - Diese besteht aus den XAML-Files und die Controls darin sind an Eigenschaften eines dahinterliegenden Viewmodels gebunden.
Das Viewmodel ist der Vermittler zwischen UI und Modell (Also Datenmodell mit Anwendungslogik) und macht im prinzip nur Folgendes: Die ausgetauschten Daten werden für die Gegenstelle (UI bzw Modell) verständlich gemacht.

INotifyPropertyChanged sollte nur im ViewModel verwendet werden, und zwar dafür, dass die UI weiß, dass sie jetzt aktualisierte Daten anzeigen muss.

Demnach würde das jetzt so aussehen:

Das EffektViewModel leitet die Daten an Effekt weiter. Dieser verändert was um OutputPin. OutputPin löst ein Event aus, dass sich ein Wert verändert hat. OutputPinViewModel registriert sich auf dieses Event und in dieser Methode löst du dann INotifyPropertyChanged auf die Property aus, welche du an ein UI-Element in deiner XAML gebunden hast.

So kannst du dann im Prinzip alles über dein Modell legen, egal ob UI, Geräte-Interface oder was auch immer - es muss halt nur auf das Event von deinem Modell reagieren.

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

17

18.02.2016, 20:30

Also angenommen, du willst statt einer UI ein Interface für ein Gerät anbinden, dann muss deine Anwendungslogik genauso das Interface darüber informieren, wenn ein Effekt einen Wert verändert hat.
Demnach würdest du also bei Veränderung des Wertes im OutputPin ein Event auslösen, welches du in der Geräteschnittstelle abfangen und weiterverarbeiten kannst.
So mache ich das im Augenblick auch... meine Lampen hier leuchten auch schon schön. :)

Das EffektViewModel leitet die Daten an Effekt weiter. Dieser verändert was um OutputPin. OutputPin löst ein Event aus, dass sich ein Wert verändert hat. OutputPinViewModel registriert sich auf dieses Event und in dieser Methode löst du dann INotifyPropertyChanged auf die Property aus, welche du an ein UI-Element in deiner XAML gebunden hast.
Jetzt hab ichs glaube verstanden wie das mit der Übermittlung funktioniert. :) Stimmt das so wie h_dev das beschreibt, BlueCobold und QuickAndDirty?

So kannst du dann im Prinzip alles über dein Modell legen, egal ob UI, Geräte-Interface oder was auch immer - es muss halt nur auf das Event von deinem Modell reagieren.
... und kann verschiedene Models an die selbe View koppeln - nur die Property Namen im ViewModel müssen einheitlich sein. Verstehe! :) Das ist schlau von MVVM.

Gut nun meine letzten zwei Fragen - hoffentlich:
- Was mache ich mit all den Eigenschaften, die nur durch die GUI (nicht durch die Models) geändert werden? Werden die in Feldern im Model gespeichert und das ViewModel greift dann drauf zu und kapselt sie mit Properties?
- Ich erzeuge nicht generell für jedes Model ein ViewModel, sondern nur, wenn ich das Model gerade in meiner GUI anzeigen möchte. Korrekt?
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

18

18.02.2016, 22:57

Stimmt das so wie h_dev das beschreibt, BlueCobold und QuickAndDirty?

Er hat nichts geschrieben was dem wieder spricht was wir geschrieben haben, er hat dir lediglich aufgezeigt wie du das implementieren könntest.

Was mache ich mit all den Eigenschaften, die nur durch die GUI (nicht durch die Models) geändert werden? Werden die in Feldern im Model gespeichert und das ViewModel greift dann drauf zu und kapselt sie mit Properties?

Also du meinst damit Eigenschaften die lediglich die GUI braucht oder ? Die sind auch im ViewModel, aber nicht Teil eines Models.
Also zum Beispiel die Farbe eines Textes, welcher sich rot färbt wenn man einen nicht zulässigen Wert eingibt ... das wäre einfach eine Color-Property des ViewModel.

Ich erzeuge nicht generell für jedes Model ein ViewModel, sondern nur, wenn ich das Model gerade in meiner GUI anzeigen möchte. Korrekt?

Ich würde das eher von der anderen Seite betrachten. Du entscheidest dich in welchen Ansichten (Views) du was editierbar (oder auch nur anzeigen) machen möchtest, daraus
kannst du dann ableiten welche Models Teil des zugehörigen ViewModels sein müssen. Alle anderen Models müssen folglich auch nicht Teil eines ViewModels sein.

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

19

18.02.2016, 23:09

Also du meinst damit Eigenschaften die lediglich die GUI braucht oder ? Die sind auch im ViewModel, aber nicht Teil eines Models.
Also zum Beispiel die Farbe eines Textes, welcher sich rot färbt wenn man einen nicht zulässigen Wert eingibt ... das wäre einfach eine Color-Property des ViewModel.
Ok, das merke ich mir schonmal. Eigenschaften (z.B. Name), die das Model selbst betreffen, müssen aber dann im Model gespeichert werden oder?

Ich würde das eher von der anderen Seite betrachten. Du entscheidest dich in welchen Ansichten (Views) du was editierbar (oder auch nur anzeigen) machen möchtest, daraus
kannst du dann ableiten welche Models Teil des zugehörigen ViewModels sein müssen. Alle anderen Models müssen folglich auch nicht Teil eines ViewModels sein.
Super, so war das auch gemeint!

Dann danke ich euch schonmal für eure geniale Hilfe - ich leg mal los mit dem Umprogrammieren und hoffe, dass das dann mal ein bisschen übersichtlicher wird! :) So nebenbei gucke ich mir jetzt auch mal Commands an - ich hab das vorher über "normale" Events (z.B. ButtonSave_Click) gemacht - das ist ein bisschen unflexibel.
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

20

18.02.2016, 23:47

Eigenschaften (z.B. Name), die das Model selbst betreffen, müssen aber dann im Model gespeichert werden oder?

Ja.


Google für die Commands einfach mal nach Action Command WPF, das ist meiner Meinung nach eine der einfachsten Implementierungen und sollte dir vollkommen genügen.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »QuickAndDirty« (19.02.2016, 00:01)


Werbeanzeige