Hallo
Als ersten Grund erstmal da uns das MVVM Pattern (Model-View-ViewModel) dies ja schon so vorgibt. OK, verstehe das dies kein nachvollziehbarer Grund ist. "Ja, nur weil das so in einem Pattern steht ist kein Grund". Kann ich verstehen. Warum das Pattern dies so vorgibt, oder besser gesagt warum es empfohlen wird ist aber interessant.
Im Normfall definiert man ein Model oder besser gesagt eine Modelklasse als sogenannte POCO Klasse. PlainOldClassObjects
Diese Klassen sind simple "dumme" Klassen. Haben also keinerlei Logik, keine Prozeduren usw.
Sie haben lediglich Eigenschaften (Properties) und definieren in einer CRUD Anwendung auch gleichzeitig die Datenstruktur. Also wie Daten gespeichert werden sollen. Evtl. sind die Eigenschaften noch mit DataAnnotations versehen, aber dann wars das schon. Damit implementieren diese Klassen auch kein INotifipropertyChanged welches wir aber für den Bindingmechanismus in der WPF benötigen. Somit können diese Klassen nicht direkt zum Binden verwendet werden. (Oder nicht gut, denn über Änderungen wird die View nicht Benachrichtigt. Sollte ja bekannt sein.)
OK, soweit ist das klar. Jetzt könnten wir aber ja hergehen und sagen wir implementieren in die Modelklasse einfach iNotifypropertyChanged. Dann können wir die Klasse ja nun super in der View verwenden und alles ist gut.
Jein. Was mache ich mit Commands? Wo packe ich nun Timer hin? Wo eigene Events? Alles dort rein? Wie schließe ich das alles beim speichern aus? Es wird unübersichtlich.
Das geht sicher eine Zeit lang gut. Plötzlich kommt der Punkt wo ich die Daten mal evtl. nicht so in der View anzeigen will wie ich diese Speichern will. Ups. Was mach ich nun. Füge ich nun eine Eigenschaft in die Klasse ein wird mir diese auch so persistiert wenn ich z.b. Serialisiere oder mittels EntityFramework oder anderen O/R Mappern in eine DB schreibe. Doof. Gut, dann biegen wir irgendwas um. Russisch. Ne, wir arbeiten sauber. Gut, also eine Klasse drumrum gebaut (was ja ein ViewModel in diesem Fall ist) aber das habe ich dann nur für diesen Fall. OK, muss ich mir merken das ich das in diesem Fall so gemacht habe.
Ich mache das lieber mit jeder Klasse von Haus aus, denn dann habe ich eine klare Designlinie des Codes, ich weis wie mein Code aufgebaut ist weil ich es immer und überall gleich mache.
Ich habe für jede Modelklasse einfach auch eine ViewModel-Klasse. Das weis ich in diesem Moment. Dort kann ich mir die Eigenschaften so machen wie ichs im View anzeigen will, ich habe dort meine Command die an die View gebunden sind, evtl. Events, Timer usw.
Jetzt kann man sagen: "Im normalfall zeige ich im View ja eh genau die Daten an die ich auch speichere"
Ne! Ich habe es immer wieder das ich das nicht mache. Ein gutes Beispiel ist z.b. eine Passworteingabe. Im View gebe ich das Passwort in ein Feld ein, das ist im Grunde ein normaler Text. Speichern will ichs aber Verschlüsselt.
Also habe ich im ViewModel eine Logik die mir das macht und in die Eigenschaft des Model-Objekts dann Verschlüsselt packt bevor gespeichert wird.
Oder ich habe in meinen Daten den Zeitpunkt der letzten Änderung eines Datensatzes als Timestamp. Anzeigen möchte ich aber Datum/Uhrzeit.
Es gibt viele Szenarien.
Ein weiterer Punkt welcher mir selbst immer wieder begegnet (aber das muss nicht auf jeden Zutreffen) ist das man oft Projekte hat welche gewisse Teile teilen müssen. Und das wäre meißt das Model.
Ein Beispiel wäre hier wenn ich eine Webanwendung für die Enduser hätte aber z.b. die Statistik oder die Administration als WPF Anwendung. Oder zwei WPF Anwendungen Eine für die USer, eine für die Admins oder die Chefs. Oder ich habe ein Webservice auf welches z.b. eine Webanwendung und eine Handy-App zugreifen. Diese Anwendungen müssen wenn Sie Daten von Webservice abrufen das Model kennen um etwas mit den Daten anfangen zu können (zumindest wirds damit um ein vielfaches einfacher).
Wenn im Model dann Abhängigkeiten wie Commands oder iregendwelche Implementierungen vorhanden sind wird oft schwierig. Unter Xamarin gibts keinen CommandManager.
Und wenn man noch länger darüber nachdenkt gibts vermutlich noch ein paar Gründe.
Es ist auch klar das es sein kann das keine dieser Gründe für einen zutreffen. Dann könnte man es probieren. Die Frage ist: Riskieren?
Wenn ich weis ich bin damit flexibler dann mach ich es. Es ist ein wenig mehr Tipparbeit. Richtig. Aber mir ist es das wert das ich weis ich bin auf der sicheren Seite und bin flexibel.
In deinem Fall (in diesem Projekt) speicherst du Gerne ja nichtmal. Also nicht als Auflistung oder sowas. Das habe ich gesehen. Im Grunde würde es diese Klasse überhaupt nicht benötigen da du in deiner Übergeordneten Klasse sowieso als simplen String speicherst. Aber um eben genau dieses Prinzip zu veranschaulichen habe ich es gleich so gebaut. Und das zeigt mir das du dir den Code auch wirklich angesehen und versucht hast zu verstehen. Dafür erstmal meinen Respekt. Und das meine ich so wie ich es schreibe. Nicht viele gehen den Code genau durch und versuchen alles zu verinnerlichen. Hut ab. So muss das, wenn man was lernen will.
So, jetzt habe ich eh wieder mal einen Roman geschrieben und bin wieder mal viel zu weit gegangen. Sorry. Hoffe es hilft trotzdem.
Wenn du noch Fragen hast, tu dir keinen Zwang an.
Grüße
Sascha
kafffee schrieb:
Warum hast du für die Klasse Genres im Model dann nochmal ne Klasse GenreViewModel im ViewModel reingemacht?
Als ersten Grund erstmal da uns das MVVM Pattern (Model-View-ViewModel) dies ja schon so vorgibt. OK, verstehe das dies kein nachvollziehbarer Grund ist. "Ja, nur weil das so in einem Pattern steht ist kein Grund". Kann ich verstehen. Warum das Pattern dies so vorgibt, oder besser gesagt warum es empfohlen wird ist aber interessant.
Im Normfall definiert man ein Model oder besser gesagt eine Modelklasse als sogenannte POCO Klasse. PlainOldClassObjects
Diese Klassen sind simple "dumme" Klassen. Haben also keinerlei Logik, keine Prozeduren usw.
Sie haben lediglich Eigenschaften (Properties) und definieren in einer CRUD Anwendung auch gleichzeitig die Datenstruktur. Also wie Daten gespeichert werden sollen. Evtl. sind die Eigenschaften noch mit DataAnnotations versehen, aber dann wars das schon. Damit implementieren diese Klassen auch kein INotifipropertyChanged welches wir aber für den Bindingmechanismus in der WPF benötigen. Somit können diese Klassen nicht direkt zum Binden verwendet werden. (Oder nicht gut, denn über Änderungen wird die View nicht Benachrichtigt. Sollte ja bekannt sein.)
OK, soweit ist das klar. Jetzt könnten wir aber ja hergehen und sagen wir implementieren in die Modelklasse einfach iNotifypropertyChanged. Dann können wir die Klasse ja nun super in der View verwenden und alles ist gut.
Jein. Was mache ich mit Commands? Wo packe ich nun Timer hin? Wo eigene Events? Alles dort rein? Wie schließe ich das alles beim speichern aus? Es wird unübersichtlich.
Das geht sicher eine Zeit lang gut. Plötzlich kommt der Punkt wo ich die Daten mal evtl. nicht so in der View anzeigen will wie ich diese Speichern will. Ups. Was mach ich nun. Füge ich nun eine Eigenschaft in die Klasse ein wird mir diese auch so persistiert wenn ich z.b. Serialisiere oder mittels EntityFramework oder anderen O/R Mappern in eine DB schreibe. Doof. Gut, dann biegen wir irgendwas um. Russisch. Ne, wir arbeiten sauber. Gut, also eine Klasse drumrum gebaut (was ja ein ViewModel in diesem Fall ist) aber das habe ich dann nur für diesen Fall. OK, muss ich mir merken das ich das in diesem Fall so gemacht habe.
Ich mache das lieber mit jeder Klasse von Haus aus, denn dann habe ich eine klare Designlinie des Codes, ich weis wie mein Code aufgebaut ist weil ich es immer und überall gleich mache.
Ich habe für jede Modelklasse einfach auch eine ViewModel-Klasse. Das weis ich in diesem Moment. Dort kann ich mir die Eigenschaften so machen wie ichs im View anzeigen will, ich habe dort meine Command die an die View gebunden sind, evtl. Events, Timer usw.
Jetzt kann man sagen: "Im normalfall zeige ich im View ja eh genau die Daten an die ich auch speichere"
Ne! Ich habe es immer wieder das ich das nicht mache. Ein gutes Beispiel ist z.b. eine Passworteingabe. Im View gebe ich das Passwort in ein Feld ein, das ist im Grunde ein normaler Text. Speichern will ichs aber Verschlüsselt.
Also habe ich im ViewModel eine Logik die mir das macht und in die Eigenschaft des Model-Objekts dann Verschlüsselt packt bevor gespeichert wird.
Oder ich habe in meinen Daten den Zeitpunkt der letzten Änderung eines Datensatzes als Timestamp. Anzeigen möchte ich aber Datum/Uhrzeit.
Es gibt viele Szenarien.
Ein weiterer Punkt welcher mir selbst immer wieder begegnet (aber das muss nicht auf jeden Zutreffen) ist das man oft Projekte hat welche gewisse Teile teilen müssen. Und das wäre meißt das Model.
Ein Beispiel wäre hier wenn ich eine Webanwendung für die Enduser hätte aber z.b. die Statistik oder die Administration als WPF Anwendung. Oder zwei WPF Anwendungen Eine für die USer, eine für die Admins oder die Chefs. Oder ich habe ein Webservice auf welches z.b. eine Webanwendung und eine Handy-App zugreifen. Diese Anwendungen müssen wenn Sie Daten von Webservice abrufen das Model kennen um etwas mit den Daten anfangen zu können (zumindest wirds damit um ein vielfaches einfacher).
Wenn im Model dann Abhängigkeiten wie Commands oder iregendwelche Implementierungen vorhanden sind wird oft schwierig. Unter Xamarin gibts keinen CommandManager.
Und wenn man noch länger darüber nachdenkt gibts vermutlich noch ein paar Gründe.
Es ist auch klar das es sein kann das keine dieser Gründe für einen zutreffen. Dann könnte man es probieren. Die Frage ist: Riskieren?
Wenn ich weis ich bin damit flexibler dann mach ich es. Es ist ein wenig mehr Tipparbeit. Richtig. Aber mir ist es das wert das ich weis ich bin auf der sicheren Seite und bin flexibel.
In deinem Fall (in diesem Projekt) speicherst du Gerne ja nichtmal. Also nicht als Auflistung oder sowas. Das habe ich gesehen. Im Grunde würde es diese Klasse überhaupt nicht benötigen da du in deiner Übergeordneten Klasse sowieso als simplen String speicherst. Aber um eben genau dieses Prinzip zu veranschaulichen habe ich es gleich so gebaut. Und das zeigt mir das du dir den Code auch wirklich angesehen und versucht hast zu verstehen. Dafür erstmal meinen Respekt. Und das meine ich so wie ich es schreibe. Nicht viele gehen den Code genau durch und versuchen alles zu verinnerlichen. Hut ab. So muss das, wenn man was lernen will.
So, jetzt habe ich eh wieder mal einen Roman geschrieben und bin wieder mal viel zu weit gegangen. Sorry. Hoffe es hilft trotzdem.
Wenn du noch Fragen hast, tu dir keinen Zwang an.
Grüße
Sascha
If _work = worktype.hard Then Me.Drink(Coffee)
Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.
## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##
Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.
## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##