Laden...

Binding eine Spalte von einer DataTable

Erstellt von _Cashisclay vor 7 Jahren Letzter Beitrag vor 7 Jahren 8.592 Views
_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 7 Jahren
Binding eine Spalte von einer DataTable

Hallo Liebe Community,

ich hab das Problem, das ich mehrere DataTables in meinem ViewModel habe, dieses dann dem DataContext zuweise und nun gerne einzelne Spalten aus einzelnen Tabellen auf TextBoxen binden möchte (via Xaml).

Ist das möglich? Hat jemand damit Erfahrung?

Ich hab schon viel beim Googlen gefunden, aber bisher hat nichts funktioniert.

Bsp:

Text={Binding Source = Kunde, Path = Rows[0][LASTNAME0]}

Grüße

F
10.010 Beiträge seit 2004
vor 7 Jahren

Du solltest dir ganz dringend noch mal anschauen wie MVVM geht.

Das VM ist dazu da die Daten für den View aufzubereiten, da gehört auch zu die Daten aus der DataTable entweder als Property oder als Liste von VM's zu erstellen.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 7 Jahren

Okay, werd ich machen, aber heißt das jetzt in erster Linie das es nicht geht?

W
872 Beiträge seit 2005
vor 7 Jahren

Du solltest eine Klasse haben, die alle Spalten zur Verfügung stellt.
Du kannst dann zum Beispiel die Instanzen der Klasse im Konstruktor mit allen DataTables instanzieren. Das ist sauber und nachvollziehbar.
Gerade wildes XAML Binding führt zu Spaghetti-Code.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 7 Jahren

Hallo,

danke für die Antworten. Ich hab gestern leider eine Menge probiert und dadurch zuvor mein Grid ein neuen DataContext zugewiesen daher ging das ganze nicht.

Für alle die diesen Beitrag sehen und eine Lösung suchen :

Wenn ihr eine DataTable habt mit nur einem Eintrag (ist bei mir der Fall) dann einfach folgendes nutzen :


<TextBox Text="{Binding EuerDataTableName.Rows[0][EuerSpaltenName]}/>

Grüße

F
10.010 Beiträge seit 2004
vor 7 Jahren

Das ist aber keine Lösung, das ist gefrickel.
Wie gesagt lese dir nochmal genau durch was MVVM ist.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 7 Jahren

Für mein Problem bzw. meine Frage ist das genau die Lösung die ich auch gesucht habe, das man das ganze eventuell anders angehen sollte und besser umsetzen kann, möchte ich nicht abstreiten, aber für meine Frage und jede andere die sich darauf bezieht, ist das erstmal eine Lösung.

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo _Cashisclay,

es funktioniert, da hast du natürlich recht. Trotzdem solltest du dir zu 100% MVVM anschauen. Auch wenn es dein Problem nicht nach den ersten beiden Sätzen, die du liest, lösen wird, ist es langfristig besser. Das Problem an deiner Lösung ist, dass es entsteht, weil du es woanders schon "falsch" angegangen hast. Das hat FZelle aber schon gesagt. Wenn du das gleiche nun nochmal machen musst, greifst du wieder auf dein "gefrickel" zurück und machst es wieder so - weil es ja funktioniert.

Daher kann ich dir nur ans Herz legen den Tipp zu berücksichtigen und dir WPF mit MVVM anzuschauen. Für deinen Code ists sicher besser.

Gruss

Coffeebean

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 7 Jahren

Hallo Coffeebean,

danke für deine Antwort. Ich werd mir das zu Herzen nehmen und mir das wirklich noch einmal ansehen. Ich kann deine Punkte zu 100% nachvollziehen. Ich hab auch schon FZelle verstanden, nur ist es immer das gleiche, ich versteh das man das Problem an der Wurzel packen möchte, aber jetzt in dem Moment habe ich eine Lösung zu dem Problem gesucht, aber FZelle als Beispiel hat 0,0 auch nur im Ansatz versucht darauf einzugehen, falls er denn darin Erfahrung hat.

Er hat wie so viele im Forum einfach die komplette Frage überworfen und unterm Strich meine Fragestellung irgendwo ignoriert .. "Ah, der macht das falsch ... Hier guck dir MVVM mal ordentlich an."

Ja, nice. Hilft mir in der Situation zwar 0 weiter, aber danke.

T
314 Beiträge seit 2013
vor 7 Jahren

Ja, nice. Hilft mir in der Situation zwar 0 weiter, aber danke.

Doch, weil es dein Problem zu 100% löst.

5.299 Beiträge seit 2008
vor 7 Jahren

MVVM studieren ist sicher nicht verkehrt.

Ist nun die Frage, ob MVVM hier nicht schon umgesetzt ist.
Weil er bindet ja an ein Viewmodel - es ist halt eine DataTable.

Und die stellt ja bereits Properties bereit - zumindest wenns eine typisierte DataTable ist.
Was aber im Xaml auch so gut wie keinen Unterschied macht - das Binden sähe fast identisch aus:

ob nun so (untypisierte DataTable):
<TextBox Text="{Binding EuerDataTableName.Rows[0][EuerSpaltenName]}"/>

oder so (typisierte DataTable):
<TextBox Text="{Binding EuerDataTableName.Rows[0].EuerSpaltenName}"/>

oder so (zwischengeschobene Viewmodel-Auflistung):
<TextBox Text="{Binding EuerDataList[0].EuerPropertyName}"/>

Nur im letzten Fall wäre ein sehr komplexes Viewmodel zwischengeschoben.

Es ist nämlich überhaupt nicht trivial, eine DataTable in eine Viewmodel-Auflistung zu wrappern. Weil es tritt (mal wieder) das Problem doppelter Listenführung auf (Liste im Model, aber auch Liste im Viewmodel) - ein KernProblem von MVVM.
(Eigentlich müsste dafür eine generische Lösung machbar sein, aber bekannt ist mir da nix)
Ja, kann man natürlich leicht einfordern vom TE, wenn man sowas nicht selbst umsetzen muss.

Oder kann jemand vlt. auf ein Beispiel verlinken, wo eine DataTable in ein Viewmodel integriert ist - das man mal konkret angucken kann, was das bedeutet?

Der frühe Apfel fängt den Wurm.

F
10.010 Beiträge seit 2004
vor 7 Jahren

Ich hatte neulich bei eurer Diskussion keine Lust etwas zu schreiben, aber der View sollte
niemals auf etwas zugreifen was außerhalb des/der ViewModels ist.

Es ist auch wirklich kein Aufwand mal eben ein Property zu machen ( hat man ja snippets für, oder?)
und auch einzelne VM ( ItemTemplates ) lassen sich in Sekunden erzeugen.

Aber wenn man immer stundenlang nach Lösungen sucht wie man da drum herum kommt dann verschwendet man Zeit und vor allem Les- und Testbarkeit.

Denn das ist es was MVVM bedeutet.
Spagettiecode braucht sowas natürlich nicht.

Speziell wenn man wie _Cashisclay einen einzelnen Wert aus einer DT an die View binden will ist doch so ein 5 Zeiler echt schnell geschrieben, statt jetzt insgesamt 2 Tage dran zu laborieren.


public string DerSpaltenName
{
    get{ return EuerDataTableName.Rows[0][EuerSpaltenName] as string;}
    set{ EuerDataTableName.Rows[0][EuerSpaltenName] = value; OnPropertyChanged(null);}
}

3.003 Beiträge seit 2006
vor 7 Jahren

MVVM in WPF Part II

bzw einzelne benötigte Properties eben über den Weg kapseln, den FZelle beschrieben hat.

Allerdings müsste mir mal jemand überzeugend einen Anwendungsfall zeigen, wo DataTable bei WPF mit MVVM ein geeigneter Container wäre. "Gefrickel" trifft es schon ganz gut.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.299 Beiträge seit 2008
vor 7 Jahren

aber der View sollte
niemals auf etwas zugreifen was außerhalb des/der ViewModels ist. naja - wer sagt, dass die DataTable ausserhalb des Viewmodels ist?
Ich sag, sie ist darinnen.

Dein PropertyWrapper berührt auch nicht das Problem der doppelten Listenführung.
Etwa die DataTable befüllen - wie ist da das Konzept?

Wenn man eine typDataTable (die ist ja bereits ein Wrapper um eine untypisierte) befüllt, kann man daran binden.

Wenn du einen Wrapper hast, musst du nach Befüllung erstmal alles umfüllen (genaugenommen musst du eine Viewmodel-Liste generieren, die aus den SubModels der Model-Liste lauter SubViewmodels generiert - also ist mehr als Umfüllen).

Und wenn der User in die Zufügezeile was zufügt - oder mit Entf-Taste was löschst - DataTable kann das, aber mit einem Wrapper - jo, musste erstmal was für bereitstellen.

Und per Code muss natürlich auch zugefügt und gelöscht werden, und wg doppelter Listenführung müssen immer beide Listen angesprochen werden - wie soll das vor sich gehen?

Edit: @Latino:
Nur kurz überflogen, aber scheint mich bisher zu bestätigen:
Das dortige MainViewmodel hat eine Property FileData vom Typ DataTable, und daran wird gebunden.

Der frühe Apfel fängt den Wurm.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 7 Jahren

Speziell wenn man wie _Cashisclay einen einzelnen Wert aus einer DT an die View binden will ist doch so ein 5 Zeiler echt schnell geschrieben, statt jetzt insgesamt 2 Tage dran zu laborieren.

Ich entnehme 26 Spalten aus der DataTable und wollte mir nicht für jede einzelne Spalte eine einzelne Property anlegen.

3.003 Beiträge seit 2006
vor 7 Jahren

Nur kurz überflogen, aber scheint mich bisher zu bestätigen

Hab' offenbar deine Frage falsch verstanden. Ich komm aber bei deinen Ausführungen insgesamt nicht ganz mit, ehrlich gesagt. Du stehst immer wieder und sehr vehement auf dem Standpunkt, dass "doppelte Listenführung" sehr komplex sei, Aufwand bedeute und in vielen Fällen grob gesagt einfach zu teuer sei. Was für eine doppelte Listenführung?!
Ein Adapter hin, ein Adapter zurück.

Wozu sollte ich bitte eine Liste der (non-UI-)Models halten, außer, um mir Arbeit mit der Synchronisation der Listen zu machen?

LaTino, verwirrt

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.299 Beiträge seit 2008
vor 7 Jahren

Das sind 2 Aussagen

  1. Du sagst, doppelte Listenführung sein kein Aufwand. 2 Adapter halt. Aber das Hinzufügen eines ViewSubmodels erfordert die Instanzierung eines SubModels, und wie das ViewSubmodel in die ViewSubmodel-Liste getan werden muss, so muss parallel dazu das SubModel in die SubModel-Liste getan werden.
    Und Löschen grad andersrum.
    Das geht bischen über Adapter hin - her hinaus.
    Kann sein, du schreibst das in 10min - ich jdfs. finde das nicht-trivial.

  2. Du sagst, doppelte Listenführung brauche man nicht. Ja, du sagst ja auch, eine Datatable brauche man nicht, ja ok, dann hast du recht.
    Insbesondere in diesem Fall hast du recht, wo der TE eh nur eine einzige DataRow zu nutzen scheint.
    Jedenfalls wenn man eine Datatable braucht, und Wrapper schreibt für die DataRows, dann braucht man auch eine Liste, wo man die Wrapper auflisten kann, weil in die DataTable kann man die Row-Wrapper ja nicht tun.
    Und dann hat man eine Liste von RowWrappern, und halt die DataTable, was ja eine Auflistung von DataRows ist.

Ist das verständlich?

Der frühe Apfel fängt den Wurm.

P
1.090 Beiträge seit 2011
vor 7 Jahren

Also wenn ich eine DataTabel, direkt an eine View Binde, habe ich das Model (Daten in Objekt Darstellung. Egal woher sie jetzt kommen) direkt an die View gebunden.

Was eigendlich nicht die Idee des MVVM Patterns ist.

Für einfache Anwendungen (die im Zweifel einfach komplett neu geschrieben werden können), ist das durchaus ein Sinnvolles vorgehen. Grundlegend brauche ich da auch so gut wie keine Zeile Code zu schreiben. Im VS kann ich die Tabel als Datenquelle hinzufügen und dann als Listen/Detail im Desiner Ansicht auf die View ziehen. Kein Problem und sehr schnell gemacht.

Bei größeren Anwendungen, die über Jahre Existieren und du gegebenen Falls mehrfach die UI oder den DAL austauschen musst. Sollte man es vermeiden.

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern

P
441 Beiträge seit 2014
vor 7 Jahren

Nur weil nach einem Anwendungsfall gefragt war:
Klassischer Anwendungsfall für das Binden einer DataTable direkt an die Oberfläche wäre das darstellen von Logdaten in Tabellenform.
Hier würde aber nicht ein Teil der Tabelle gebunden werden sondern die gesamte Tabelle als DataView, bietet sich vor allem dann an, wenn vom eingelesenen Log abhängt wie die Formate sind und das beim Design des Programms nicht bekannt sein muss/ist.

F
10.010 Beiträge seit 2004
vor 7 Jahren

Sorry, aber ich persönlich halte überhaupt nichts von DataTables, da sie nicht typisiert sind und deswegen das gefrickel fördern.
Und eine typisierte DataTable ist nur gefrickel über gefrickel.

Was ist so verd... schwer daran mal in 2 Minuten eine Klasse zu schreiben die die Daten in nativer Form hält?
Die kann man genau so zum visuellen DataBinding benutzen, die ist viel leichtgewichtiger, testbar usw.

Statt immer wieder mit dem Frickelkram zu arbeiten, sich ständig irgendwas ausdenken zu müssen um das irgendwie hinzubekommen, macht man es doch lieber gleich richtig.

5.299 Beiträge seit 2008
vor 7 Jahren

Hier hab ich mal son Gefrickel-Gefrickel.

Ein kleines Warenhaus mit Artikel, Kategorien und Lieferanten.

Vollständiger Crud-Support aller Datensätze, m:n - View in beide Richtungen, Laden, Speichern und die Daten sind auch im Zip enthalten.
"m:n - View in beide Richtungen" bedeutet:

  1. Ansicht der Artikel (einschließlich Lieferant) nach Kategorien
  2. Ansicht der Artikel (einschließlich Kategorie) nach Lieferanten
    Mittels ComboboxColumn kann dem Artikel eine andere Kategorie/Lieferant zugeordnet werden.

Ich lade dich ein, das eben mal umzuschreiben, dasses kein "Gefrickel" mehr ist.
Vorzugsweise ohne dass ich groß was nach-installieren müsste, also IOC, SqlServer, Prism etc. - ist bei mir immer ein Unsicherheitsfaktor, ob ich das gebacken kriege.

Edit:
Bitte an die Moderation: Kann man die Diskussion "doppelte Listenführung" etc. abtrennen?
Imo ab dem Post von 13:58 wird hier verhandelt, was der TE garnet gefragt hat, und sein Thema hatte er ja selbst gelöst, schon um 10:10.

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

Hab's mir mal angeschaut. Dein ViewModel ist keines. Die Steuerung der UI wird direkt vom Datenmodell (und ich rede nicht vom ersten "M" in MVVM) übernommen, das "ViewModel" weiß zu keiner Zeit vom Zustand der UI, dafür führt es aber Aufgaben aus, die UI-Sache sind (System.Media.SystemSounds.Asterisk.Play();) - das geht selbst über meine recht freie Definition von MVVM weit hinaus. Na klar funktioniert das. Aber du hast genau gar keine Schichtentrennung.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.299 Beiträge seit 2008
vor 7 Jahren

ja, ich weiß - alles ganz schrecklich - ein grauenhaftes Gefrickel von 30 Zeilen Code leistet die genannten Features:
Voll-Crud im bidiraktionaler m:n-View, laden und speichern, und TestDaten sind auch gleich mit drin.

Ich wollte mal sehen, wie ihr das "besser" macht, das ist der Punkt - könnt ihr das, und wird das Ergebnis - wenn ihr die Herausforderung überhaupt annehmt - mich auch überzeugen?

ZB - wenn man da ein richtiges Viewmodel zwischenschiebt, ich denke, da steht man dann vorm Problem der doppelten Listen-Führung.

Beachte auch, dass mein Sample auch als MVVM bezeichnet werden könnte. Zumindest was du als MVVM-Artikel verlinkt hast, ist kein Deut besser - dort wird auch an eine DataTable gebunden.
Und was da als "Model" bezeichnet wird ist keines, sondern ist ein Repository.
Weil imo ists ein Unterschied, ob etwas Daten heranschafft, oder ob wirklich Zusammenhänge modelliert sind.

PS:
"gar keine SchichtenTrennung" findich doch ein krass übertriebenes DownRating. Die View ist absolut klar getrennt vom anderen.
Nur Model, Viewmodel, Repository sind nicht ausdifferenziert.
Wenns am SystemSounds.Play() liegt - dann lösch die Zeile.
Oder sieh's als Provisorium - klar kann man da nu Dateien anlegen, WeakEvents einrichten, auslösen, in anderen Klassen dann empfangen - dass es am ende doch nur wieder "Plink!" macht.
Es deutet halt an, dass ein Feedback wünschenswert ist, wenn ein Speicher-Vorgang erfolgreich war.
Ich finde nicht, dass die Trennung von View und Model steht oder fällt, nur weil ich das in einer Zeile abhandle.

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

Nein, du hast einen View, den du per Databinding an ein fertiges Datenmodell bindest. Das heisst du benutzt Databinding, ja. Das war's aber auch, die Trennung von der UI wird ausschließlich durch das Binding erzeugt, nicht etwa dadurch, dass Schichten existieren würden.

Du kannst gern den Overhead, den das DataSet/DataTable erzeugt, mit zu den 30 Zeilen Code zählen. (EDIT: hätte ich anders formulieren sollen. Sagen wir so: da du kein funktionales MVVM implementierst, sind deine M/VM-Klassen sehr kurz, das ist wahr. Sehr kurz ist in deinem Beispiel auch, was weiß ich, sagen wir, der Part mit der schachspielenden KI. Das heisst aber nicht, dass es ein gutes Beispiel für eine schachspielende KI ist 😉 )

Und nein, dein VM ist nicht nur nicht ausdifferenziert, es ist nicht existent. Gebunden wird die UI direkt an eine Eigenschaft der "MainViewModel"-Klasse. Ein ViewModel bildet aber die UI (und deren Workflows!) ab und dient ihr nicht bloss als Container für die darzustellenden Daten.

Das Projekt hat vom MVVM-Part nur den View, nicht mehr. Dann könnte ich dir auch einen Football in die Hand geben und sagen "zeig mal, wie du damit ohne Aufwand Golf spielen willst!".

Die Trennung von View, Model und ViewModel steht und fällt damit, dass jeder Part klar formulierte Aufgaben hat. Diese Aufgaben sind innerhalb des MVVM-Patterns klar definiert. Wenn du sie ignorierst (und das tust du), kannst du nicht einfach eine Klasse "MainViewModel" nennen und dann behaupten, du hättest ViewModel. D.h. du kannst das schon machen, es hat nur nichts mit dem Thema MVVM zu tun.

Noch ein Edit: Um das zu veranschaulichen: sagen wir, du willst deine UI wirklich steuern. Simples Beispiel - eins der DataGrid soll vorsortiert sein. Dein "MainViewModel" weiss aber gar nichts darüber. Es muss im Gegenteil mangels Model direkt in das Datenmodell greifen. Zum einen, wäre es MVVM, sollte das VM das Datenmodell nicht kennen. Zum zweiten sollte es selbst die Prozesse der UI abbilden. Tut es beides nicht. Die dargestellten Daten sind nicht im Scope des Oberflächen-Entwicklers, sondern des Daten-Entwicklers. Letzterer hat damit auch, ohne es zu wissen, die Kontrolle darüber, wie die Oberfläche aussieht. Das riecht nach Ärger.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.299 Beiträge seit 2008
vor 7 Jahren

Das ist doch jetzt Wortklauberei.

Immerhin erkennst du, dass ich ein View habe. Und du erkennst, dass da noch etwas anderes ist.
Von dem ich ja selbst sage, es ist nicht ausdifferenziert. Ich hab nun leider kein Wort dafür: wenn ich es Model nenne, widersprichst du mir, wenn ich es Viewmodel nenne widersprichst du mir auch.

Den DatasetDesigner-Code zähle ich nicht zum UserCode, denn ich habe ihn nicht coden müssen.
Um die Anwendung zu verstehen muss man den DesignerCode auch nicht angucken, sondern man muss den DatasetDesigner angucken, um das Datenmodell zu verstehen, das MainWindow um die Oberfläche zu verstehen, und die MainViewmodel-Klasse, an die die Oberfläche gebunden ist.
Und darin habe ich kaum 30 Zeilen Code schreiben müssen, für diese Anwendung.

Aber ich hab den Eindruck, man ziert sich, die Herausforderung anzunehmen, und eine ebenfalls eine praktische Umsetzung anzubieten, dass man mal gucken kann, wie MVVM "richtig" geht.
Hat man natürlich gut reden, aber das sind nur Reden.

Ich hab übrigens auf Codeproject noch weiter herumgesucht, nach einem MVVM-Artikel, wo überhaupt mal ein Model auftaucht, was eine Liste enthält - bislang keins gefunden.

hier: http://www.codeproject.com/Articles/278901/MVVM-Pattern-Made-Simple gibts überhaupt kein Model - noch weniger als bei mir.

hier: http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial besteht das "Model" aus einer Song-Klasse, es gibt keine Interpreten, keine Alben, und logisch sind auch keine Zusammenhänge modelliert - nichtmal eine Auflistung von Songs gibts im Model.

Jo - mit so Primitiv-Models sieht MVVM dann schmissig aus, und hat auch kein Problem mit doppelten Listen.
Aber mir kommt das vor wie Drückebergerei bzw. auch ein die Augen vor etwas verschließen

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

Ich sagte ja, kann man machen, und funktioniert auch. Nur ist es, wie du sagst, eine schwammige Trennung der Verantwortlichkeiten, und ganz sicher, wie ich begründet habe, keine MVVM-Implementierung. Die DataSet/DataTable-Geschichte ist sicherlich bequem - weil sie ursprünglich entworfen wurde, um genau das zu machen, was du gemacht hast (zwar in Windows.Forms, aber - geschenkt). Was erwartest du jetzt? Dass ich oder jemand anders dein Projekt auf MVVM umzieht, und so lange vergrößert, bis von dir ein "okay, jetzt ist der Aufwand für MVVM gerechtfertigt" kommt? Wozu sollte das gut sein (außer, dass jemand sein Wochenende verschwendet)? Und wenn es dann 20 Zeilen länger ist, diskutieren wir darüber, dass MVVM viel zu aufwändig ist, und ignorieren dabei völlig den Fakt, dass der Sinn von Schichtentrennung nicht ist, weniger Code zu produzieren, sondern besser managbaren Code zu produzieren? Also, was wäre damit bewiesen?

Netter Versuch mit dem "man ziert sich". Die Abwägung zwischen Freizeit und einem kurzen "achso, aber..." von dir ändert sich aber nicht dadurch 😉. Dir ist doch völlig klar, dass die Lösung in deinem Projekt quick&dirty ist (siehe auch den Beitrag von Palin, da ist an sich nix hinzuzufügen). Also muss dir auch niemand beweisen, was du schon weißt.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.299 Beiträge seit 2008
vor 7 Jahren

naja, die Lösung ist nicht quicker und dirtiger als in allen MVVM-Tuts, die mir bekannt sind.

Mir zu beweisen, was ich schon weiß - da hab ich tatsächlich kaum was von. Was ich erwarten täte? Naja, euch beim Wort nehmen halt. Ihr wisst so toll, wie "richtiges" MVVM geht, aber mal ein Beispiel vorlegen, so wie ich es tue, - da kommt dann nixme.

Aber vlt. sollte ich zwei Sachen auseinander halten: Also von FZelle ärgert mich, dasser "FrickelFrickel!" schimpft, und in 2 Minuten könne man es "richtig" machen.
Nur erbringt er keinen Nachweis dessen.

Bei dir ärgerts mich weniger - hätte mir halt erhofft, mal eine Lösung zu sehen, die aufzeigt, wie "richtiges" MVVM das im Viewmodel löst, wenn im Model eine Auflistung von SubModels auftritt, oder gar eine m:n-Relation.
Da drücken sich ja ausnahmslos alle mir bekannten Tutorials drum herum, und auch ihr scheint das Problem nicht sehen zu können.
Wenn Ihr's mal probiertet, vlt. würdet ihrs dann sehen. Oder aber es würde es mir etwas neues aufzeigen.

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

Weil's so schön ist und exakt meinen Punkt stärkt, kleine Zwischenmeldung.

  • 10 Minuten für die UI-Modelklassen
    ...dann bau ich mir, was der Hauptpunkt ist, weshalb ich vor dem Beispiel zurückgeschreckt bin (du weisst, was ich vom DataSet-Designer halte, für alle anderen: das Ding ist wie Hitler, nur unsympathischer), also, dann baue ich mir einen DataProvider, der die Schnittstelle zwischen dem Dataset, dass ich als Datenmodell zu benutzen gedenke, und den UI-Modellklassen darstellt.

Stell' dir meine Überraschung vor, als ich feststelle, dass man mit deinem Datenmodell (z.B., nicht der einzige Defekt) gar nicht (sauber) einen Artikel von mehreren Lieferanten liefern lassen kann. Wir haben also ein defektes Datenmodell. Im MVVM-Normalfall wäre das völlig egal. In diesem Fall hier sorgt es dafür, dass ich selbst die Tabellen umstrukturieren muss, das Datenmodell ändern muss, am DataSet basteln darf (danke, vielen, vielen Dank)...oder alles wegwerfe und mir "fix" ein eigenes, funktionierendes Datenmodell baue.

Und deshalb ist das direkte Binden von Datenmodell an den View Mist.

LaTino
Edit, Disclaimer: die fehlende/falsche Relationsbehandlung kann passieren, und hätte mir auch selber sofort auffallen müssen. Darum geht's nicht 😃

Edit: so, hängt dran. Anmerkungen:

a) ~60-70% der Zeit hat mich der DataProvider und die Korrektur des Datenmodells gekostet
b) das UI-Model unterstützt die Änderung der Relationseigenschaft "Preis" der Lieferant-Artikel-Relation, aber die UI tut das nicht. In plain language: das neue Datenmodell hat eine Relation Lieferant-Artikel (1:n), die eine Eigenschaft "Preis" hat. Das lässt sich mit einem GridView nicht ohne Weiteres oder wenigstens nicht ergonomisch abbilden, ich müsste im vierten DataGrid (r.u.) eine Combobox für den Artikel nutzen, die gleichzeitig Auswahl des Artikels und Editieren des Artikelnamens erlaubt. Das ginge zwar, widerspricht aber üblichen UI-Patterns. Ist aber ein anderer Aspekt, der nix zum Thema beiträgt, deshalb - weggelassen.
c) DataSet entfernt. Hab ich erwähnt, dass ich das Ding hasse? Mag sein, dass jetzt das Datenmodell schwerer nachzuvoollziehen ist (siehe Data\example.xml), dafür ist es korrekt.
d) Menü ist dysfunktional, da ich darauf keine Lust hatte und es auch nix zur Sache tut 😉

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

F
10.010 Beiträge seit 2004
vor 7 Jahren

@ErfinderDesRades:
Komisch, vor garnicht all zu langer Zeit ( wirklich schon wieder ein jahr ) habe ich dir mal privat und per Mail eine Demo für die Benutzung eines ORMappers gemacht.

Habe darin gezeigt wie man mal mit einem ORMapper statt DataSets arbeitet und lese trotzdem immer und immer wieder von Dir hier das du die untypisierten Monster immer noch benutzt.

Ansonsten hat LaTino alles geschrieben was dazu zu sagen ist.

Wenn du kein MVVM machen willst, schön für dich, behaupte aber nicht das du es tust ( machst du offensichtlich nicht ).
Und da du es nicht machst, kannst du ganz offensichtlich nicht beurteilen welche Vorteile in der Pflege einer immer grösser werdenden Software das bringt.

Wie gesagt, mach was du willst, aber behaupte nicht du machst MVVM.

5.299 Beiträge seit 2008
vor 7 Jahren

naja - dann behaupte ich halt, ich mach so, wie in den mir bekannten MVVM-Artikeln von CodeProject gezeigt. 😁
Wobei keiner dieser Artikel euren Ansprüchen an MVVM gerecht werden würde.
Artikel, die euren Ansprüchen an MVVM gerecht werden würden, sind mir leider nicht bekannt.

Oder vlt. doch, zB kam neulich ein VierGewinnt-Monstrum auf, zu dem ich notiert habe:
"Dieses ist ausse Dropbox gezogen, und steht im Zusammenhang mit einer utube-reihe/Vorlesung zu Wpf
https://www.youtube.com/watch?v=jOCrux6MJ7g
https://dl.dropboxusercontent.com/u/14810011/VierGewinnt.zip"

Ist vlt. wirklich ein gutes Beispiel, weils aufzeigt, wie umfangreich das ist, was ihr euch unter "richtigem" MVVM vorzustellen scheint.
Und besonders wartbar findich das nicht, sondern es enthält jede Menge Zeugs, was keine Funktion erfüllt, und entfernt gehörte.
Ausserdem gibts leider auch nichts her zur doppelten ListenHaltung: es gibts zwar Listen im Model, aber kein dynamisches zufügen/entfernen.


Es sind übrigens typisierte "Monster" (Datasets), die ich verwende - keinesfalls untypisiert.
Jo, benutze ich immer noch. Weil typDataset als Datenmodell hat noch immer als Alleinstellungsmerkmal den Vorzug, das mans direkt auf Platte speichern kann, und keine Abhängigkeiten eingehen muss zu Zusatzbibliotheken, Datenbanken, Datenbank-Installations-Umgebungen etc..
Aber das Thema hat ja auch nix mit MVVM zu tun - Für MVVM ists doch egal, ob ein Model aus TypedTable<TRow> besteht oder aus LinqToDB.ITable<TEntity>
Auch dein gemailtes Beispiel hat nix mit MVVM zu tun - es ist ja eine WinForms-Anwendung.

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

Ausserdem gibts leider auch nichts her zur doppelten ListenHaltung: es gibts zwar Listen im Model, aber kein dynamisches zufügen/entfernen.

Du solltest wirklich mit dem Mantra der doppelten Listenhaltung aufhören. Im Beispielprojekt oben wird nirgends eine Liste doppelt geführt, und dennoch kann man dort leicht Items hinzufügen oder entfernen.

Das ist nur und wirklich ausschließlich notwendig, wenn man die Daten mittels eines DataSets verwaltet. Und wie ich schrieb, ist das DataSet das falsche Werkzeug, weil's gar nicht dafür entworfen wurde. Ob typisiert oder nicht, spielt keine Rolle. Auch das typisiertes DataSet ist ein Code-Monster, das für schichtentrennende UI-Patterns (egal ob sie MVVM oder MVC oder MVP heissen) völlig ungeeignet ist, weil es eben keine Schichtentrennung propagiert.

Und der 4Gewinnt-Code oben ist aus einer Vorlesungsreihe. Der hat da alles an Entwurfsmustern und Designmustern reingepappt, was auch nur halbwegs passend schien. Für die Vorlesungsreihe super, weil man echt viele Techniken kennenlernt, aber recht weit weg von der Praxis. Dort die Maßstäbe einer Oberfläche einer Produktivumgebung anzulegen, ist unangemessen, und das weißt du auch.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.299 Beiträge seit 2008
vor 7 Jahren

Du solltest wirklich mit dem Mantra der doppelten Listenhaltung aufhören. Im Beispielprojekt oben wird nirgends eine Liste doppelt geführt, und dennoch kann man dort leicht Items hinzufügen oder entfernen. ja, offsichtlich einer von uns beiden kapierts nicht.
Und jeder glaubt, der andere isses.
Ich kanns dir nicht beweisen, dass das ein Problem ist, du könntest es mir beweisen, dasses kein Problem ist. Aber dazu müsstest du mal Hand anlegen und nicht nur sagen soundso. Oder vlt. würdest du dabei das Problem dann eben doch noch verstehen.
Btw In welchem Beispiel meinst du, kann man Items zufügen?

Und dass ein typDataset Schichtentrennung unmöglich macht ist ja quatsch. Warum soll man denn keine Viewmodelse zu basteln können, die halt typDataRows kapseln anstatt iwelche anderen Entity-Klassen?

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

Im Beispiel oben, für das ich mir etwas Arbeit gemacht habe und das du gepflegt ignorierst.

Und nein, ist kein Quatsch. Weil ich nicht schrieb, dass es das unmöglich macht. Leg mir bitte keine Worte in den Mund.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.299 Beiträge seit 2008
vor 7 Jahren

Im Beispiel oben, für das ich mir etwas Arbeit gemacht habe und das du gepflegt ignorierst. Ich schwöre!

Das - der Anhang - war vorhin noch nicht da!
Ich hab den Post ühaupt nicht verstanden, wovon du da redetest.

Also vielen Dank schoma und ich guck nu.

Ah - ja!
Du erstellst gar keine Viewmodel-Klassen, die die Model-Klassen wrappern.
Ich hätte ja nu vom "richtigen MVVM" erwartet, dass es zu Artikel ein ArtikelViewmodel gibt und zu Category ein CategoryViewmodel usw..

Bist du sicher, dass das MVVM ist?

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

Ich schwöre!

Das - der Anhang - war vorhin noch nicht da!
Ich hab den Post ühaupt nicht verstanden, wovon du da redetest.

Also vielen Dank schoma und ich guck nu.

Womöglich 'n Cache-Problem oder was, weil ich es erst in einem Edit hinzugefügt habe.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

3.003 Beiträge seit 2006
vor 7 Jahren

Mal kein Edit, weil das vorher OT war.

Krieg das jetzt nicht in den falschen Hals, bitte 😉.

Ich habe den Eindruck, dass du MVVM gar nicht richtig verstanden hast. Wie ich oben schon einmal schrieb: dieses Modell versucht, die Aspekte einer UI aufzutrennen nach:

a) Model - wir reden NICHT von Datenmodell. Wir reden von einem Modell der Daten (mwaha), wie sie in der UI dargestellt werden. Wollte ich beispielsweise in einem DataGrid eine Spalte, die irgendwie einen erläuternden, dynamischen Text aus einer anderen Spalte macht, würde ich diese Spalte im UI-Modell hinzufügen und NICHT wie in der Forms-Welt im CellFormatting-Event. Das bedeutet auch, dass die UI-Modellklassen nicht direkt an die UI gebunden werden, sondern (maximal) als Eigenschaften des ViewModels. Modellklassen können auch Klassen sein, die gar nicht dargestellt werden, sondern dem VM beim Steuern der UI helfen.

b) das ViewModel. Das VM kennt die Modellklassen, aber nicht den View. Es bildet die Workflows des Benutzers ab, und die entstehen im View dann dadurch, dass der View an das VM gebunden ist.

c) der View kennt im besten Fall gar nichts außer den Schnittstellen des ViewModels, an das er gebunden ist. Man beachte, dass ich "Schnittstellen" schrieb. Über den aktuellen Zustand oder die konkrete Art seines ViewModels weiß der View nichts.

In dem zugegeben sehr einfachen Fall oben entsteht die Dynamik einzig und allein durch die Organisation der Modellklassen. Die halten untereinander 1:n-Beziehungen und sonst gar nichts, was übrigens auch der Grund ist, wieso deine Implementierung mit DataSet so gut funktioniert hat. 1:n-Beziehungen sind aber der zweiteinfachste Fall (1:1 wäre der einfachste) einer Beziehung. Dass durch das Verbinden mehrerer Relationen was Komplexeres entsteht - völlig egal. Ich muss die Komplexität nicht abbilden, sondern ausschließlich die Entitäten:

  • Objekt-Entitäten Artikel, Kategorie, Lieferant
  • Relationsentitäten Artikel-Kategorie (im Beispiel aus Bequemlichkeit auch gleich die Gegenrichtung)
  • Relation Artikel-Lieferant mit angehängter Entitätseigenschaft "Preis".

Da muss sich niemand mit irgendwelcher Listenhaltung um die Konsistenz kümmern. Die Objekte sorgen selbst dafür. Im Endeffekt bilden wir die Situation mit Objekten ab (das wäre dann das Modell, hence the name) und stellen sie mit Hilfe des ViewModels dar.
View: grafische Schicht
ViewModel: Abbildung der grafischen Schicht und ihrer Logik
Model: Abbildung der zugrunde liegenden Situation.

Jetzt verstehst du vielleicht, wieso so vieles von deinen Argumenten, wie ich ganz oben mal schrieb, unverständlich bleibt.

LaTino
Edit: MVVM hat ganz entscheidende Schwächen, aber die liegen eher darin begründet, dass sehr viele VM-Umsetzungen einige der SOLID-Prinzipien verletzen, weil MVVM diese nicht propagiert, sondern im Gegenteil eine Verletzung insb. von single responsibility sehr leicht und verführerisch macht. Das sind Kritikpunkte, die man anbringen kann, aber deine kann ich nicht nachvollziehen.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.299 Beiträge seit 2008
vor 7 Jahren

Vielen Dank, da mussich glaub noch drüber nachdenken. Kann auch Weilchen dauern, da grad viel zu tun.
Noch zum "in den Mund legen": Also ich hab dein "DataSet ist [...] völlig ungeeignet [...], weil es eben keine Schichtentrennung propagiert." als Behauptung von Unmöglichkeit verstanden.
Aber auch von der Behauptung "völliger Uneignung" bin ich sehr unüberzeugt.
Aber ich muss noch behirnen, obs mir Sinn macht (oder eben nicht), "Model" iwie anders zu verstehen als was ich unter Datenmodell verstehe.

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

Du solltest vor allem verstehen, dass ein Ausdruck wie

ArtikelViewmodel [..] CategoryViewmodel

..aus MVVM-Sicht überhaupt keinen Sinn ergibt. Ein ViewModel modelliert einen View. CategoryViewModel würde einen View modellieren, der Kategorien darstellt. Es gibt kein Model des Datenmodells (i.e., das gibt es schon, wenn man "Datenmodell" als das interpretiert, was die DAL ausspuckt, aber dann wäre die Bezeichnung einfach Model und hätte nichts mit dem Begriff zu tun, den du gemeint hast).

Siehe dazu auch den ausnahmsweise recht guten Wikipedia-MVVM-Artikel. Oder die Einführung von Microsoft.

Ich weiß jetzt nicht, wie vertraut du mit MVC oder besser noch MVP bist (ich fürchte fast, dein DataSet-Fetisch 😉 verwässert auch diese UI-Pattern unter Forms etwas), aber der Schritt von MVP zu MVVM ist minimal, da besteht in weiten Teilen kein Unterschied. MVVM beschreibt allerdings besser die Abläufe innerhalb einer WPF-Oberfläche.

Wichtig auch, beim genaueren Nachdenken, dass du dir noch einmal klar machst, dass die UI-Pattern einzig und allein für die Trennung der Verantwortlichkeiten innerhalb einer UI da sind. Deshalb unterscheidet sich das Model in MVVM auch vom Modell der Daten in DAL oder Businness-Schicht. Das ist auch der Vorwurf an das DataSet: es stellt eigentlich eine Datenzugriffsschicht dar, die in der Oberfläche gar nichts verloren hat. In meinem Beispiel hat eigentlich auch der DataProvider nichts im VM zu suchen, an der Stelle war ich unsauber, aber pragmatisch. (An sich sollte der DataProvider irgendwo beim Erzeugen des ViewModels benutzt werden, um dem ViewModel die Daten zu übergeben, im Beispiel also im Applikationskontext.)

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 7 Jahren

Hey ho,

war über das Wochenende nicht Online. Werd mich die Tage aufjedenfall noch einmal mehr mit dem MVVM auseinandersetzen.

Wenn ich das halbwegs richtig verstanden habe (und ich trau mich kaum noch etwas zu dem Thema zu sagen) soll ich anstatt meine "frimel" Lösung zu nutzen mir einfach statt der Property wo das DataTable drinne ist woraus ich meine Daten ziehe, für jede Spalte aus der DT eine Property anlegen und dort den Wert hinterlegen um dann das ganze zu Binden.

Grüße

3.003 Beiträge seit 2006
vor 7 Jahren

Das "Problem" ist, dass die DataTable dir Arbeit abnimmt, aber deine Objekte sozusagen als Datenzeilen "maskiert". Du kannst dann auch nicht mehr damit machen, als eine DataRow dir erlaubt.

Im MVVM soll das Modell der Daten aber genau abbilden, was die dargestellten Daten halt so können. DataTable kann oft mehr als benötigt (was nicht gut ist), und gleichzeitig nicht immer alles, was man braucht (was erst recht nicht gut ist).
Und dann fängt man an, an den einzelnen Datenzeilen zu schrauben und Spaghetticode zu schreiben, um das Problem zu fixen, was man von vornherein nur hatte, weil man einen DataTable benutzt hat. Genau, was du schreibst: jetzt würdest du als nächstes alle Spalten deiner Tabelle als Properties abbilden. Das ist ein Haufen Tipparbeit, den du nur hättest, weil du nicht mit "richtigen" Datenklassen gearbeitet hast, sondern die Daten einfach in eine DataTable geknallt hast.

An der Stelle hast du aber noch die Freiheit zu entscheiden, ob diese Tipparbeit wirklich nötig ist. Schlimm ist es erst, wenn du irgendein Feature brauchst, dass du mit der DataTable nicht oder schwer abbilden kannst, denn dann MUSST du dir die Arbeit machen. Insofern alles (noch) nicht so schlimm.

Noch eine Anekdote aus'm Krieg 😉 : Früher[tm] gab es noch gar kein DataGrid in der WPF. Und das war nicht, weil MS faul war, sondern weil man erkannt hatte, dass das DataGridView aus der Windows.Forms zuviel konnte und den Programmierer in eine bestimmte Richtung gezwungen hat (nämlich die Verwendung von DataTable und DataSet), was der Codequalität nicht immer förderlich war. Das wollte man in WPF vermeiden - allerdings war der Protest der Windows-Forms-Veteranen so groß, dass man es mit all seinen Nachteilen wieder eingeführt hat. In WPF sollte man sich immer zwei Fragen stellen:

a) brauche ich hier WIRKLICH ein DataGrid?
b) muss ich das Grid WIRKLICH mit einer DataTable verbinden?

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 7 Jahren

Ich zieh mir die Daten aus der Datenbank und leg die in eine DataTable, ist doch eigentlich am besten um die Daten sauber aufzubereiten oder nicht?

3.003 Beiträge seit 2006
vor 7 Jahren

Ja und nein.

Stell dir die Frage, ob deine Oberfläche davon abhängig sein sollte, wo die Daten herkommen und wie sie in der Datenbank aussehen. Das ist einer der Knackpunkte der Diskussion oben 😃. Je "dümmer" eine Oberfläche ist, desto flexibler bist du damit. Nimm ihr also das Wissen, das sie nicht braucht, und gib dieses Wissen jemandem, der darauf spezialisiert ist, dafür dieses Wissen braucht, und der Oberfläche dann sagen kann, was sie darstellen soll. Und schwupps, hast du Verantwortlichkeiten getrennt, kannst den XAML-Part der Oberfläche einem Designer geben, machst selbst nur das ViewModel (sagst der Oberfläche, wann sie was machen soll), und schiebst das Einlesen aus der Datenbank deinem Datenbank-Fuzzi rüber. Um nur ein Beispiel zu nennen.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

F
10.010 Beiträge seit 2004
vor 7 Jahren

Ich zieh mir die Daten aus der Datenbank und leg die in eine DataTable, ist doch eigentlich am besten um die Daten sauber aufzubereiten oder nicht?

Nein.
MS hat die DataTable in FW 1.0 nur eingeführt weil sie damals die ganzen VB6 Programmierer im Blick hatten.

Und denen hat man dann mit der typlosigkeit einen "großen gefallen getan", wobei die meisten VB6 Entwickler nach 17 Jahren immer noch "ihrem VB6" nachjammern.

Ich habe in den letzten 15 Jahren eigentlich kaum professionelle Software gesehen die nicht spätestens nach version 1 immer statt DataSet/DataTable auf einen wie auch immer gearteten ORMapper umgestiegen ist.
Selbst MS hat schon in FW 1.1 eingesehen das was typisiertes her muss und hat diese schrecklichen Codemonster von typisierten DataSets entworfen.

"Die Gemeinde" hatte damals aber schon ORMapper wie NHibernate, ActiveRecord, Retina und co entdeckt so das MS dann doch irgendwann, erst mit Linq2Sql und später mit dem EntityFramework, ORmapper gebaut hat.

Heute gibt es da so viel Auswahl die man vom Miniprojekt mit SQLite-Net oder Linq2DB bis hin zu EF hat, das man eigentlich Datasets nicht mehr benötigt.

Aber genauso wie die VB6ler gibt es Leute die mit DS/DT glücklich sind und damit alles machen.
Aber benutzen müssen muss/sollte man das nicht.

5.299 Beiträge seit 2008
vor 7 Jahren

@Latino: So, hab jetzt mich eine Weile mit deim Input und mit deim Projekt beschäftigt, únd versuche mal was für mich zusammenzufassen.

Also neu für mich war, dass du ganz unbefangen auch an Model-Klassen bindest. Ich bin bislang immer vom MVVM-Puristen-Dogma ausgegangen, dass jede Model-Klasse in eine Viewmodel-Klasse konvertiert werden muss, sonst darf Xaml nicht dran binden (oder es ist kein MVVM).
Wie gesagt: Das habe ich für die "reine" MVVM-Lehre gehalten, und mich selbst darüber hinweggesetzt, wenn opportun. Wenn das eh eine Irrlehre war, umso besser.

Deinen/euren Aversionen gegen typDatasets schließe ich mich nachwievor nicht an.
Manches, was du/ihr gegen typDatasets vorbringt, verstehe ich nicht: was ist eiglich 'Schichtentrennung propagieren', und warum propagiert deine Article-Klasse diese, meine ArticleRow-Klasse aber nicht?

Anderes stimmt nicht

Du kannst dann auch nicht mehr damit machen, als eine DataRow dir erlaubt. an typisierte DataRows kann man (wie an jede andere Klasse auch) Methoden und Properties dranprogrammieren, wie man will - "nicht mehr, als DataRow erlaubt" ist definitiv falsch.

Anderes - Stichwort "Codemonster" findich in vielen Fällen nicht weiter tragisch: das Monster kann halt viel - v.a. ich muss das Monster ja nicht coden. Manch selbstgecodete Alternative ist ebenfalls monströs, andere sind schwachbrüstig, andere sind buggy. (Wenn ich wollte könnte ich einige Schwächen deiner DataProvider-Lösung behühnern - insbesondere Xml lesen/schreiben ist ja gradezu phantastisch mit typDataset)

Aber wie man zu typDataset steht ist mir ATM nicht First-Topic.
Einzig ich behaupte, es sind Klassen, und Klassen kann man natürlich in Viewmodels einbeziehen, wenn man will - oder was sind da die Ausschlusskriterien?

Gut, also ich meine gelernt zu haben, das View darf auch an Model-Klassen binden - worin besteht denn dann eiglich noch der prinzipielle Unterschied unserer Anwendungen?
Ob du nun an Article-Objekte bindest, oder ich an ArticleRow-Objekte - ist ja nix prinzipielles (oder?).
Als prinzipiellen Unterschied fand ich, dass mein Viewmodel sich selbst von Platte liest, und bei dir gibts einen Umfüll-Vorgang dazwischen.

Diesen Umfüll-Vorgang hättest du sogar weglassen können - dein DataProvider enthält drei List<T>, die werden umgefüllt in drei ObservableCollection<T>, und weiter passiert mit den List<T> nichts.
Aber das trennt immerhin dein Model vom Viewmodel, und macht es denkbar, dass dein Model - dessen derzeit enthaltene Daten 100% identisch sind mit den Viewmodel-Daten - also dieses Model könnte auch wesentlich mehr, und auch andere Daten enthalten, oder die Daten auch in anderen Datenklassen darstellen.
Entkoppelt eben.

Bei mir nicht - mein Sample ist also VVM statt MVVM - ich finde, ggfs. kann man pragmatischerweise ganz gut damit leben.
Und wenn ich nun einfach ein zweites Dataset hätte, nur zum Einlesen, und würde ebenfalls einen Umfüll-Vorgang zwischenschalten - mw in ein MainViewmodel-Dataset, dann könnte ich doch wieder in Anspruch nehmen, prinzipiell "richtiges" MVVM zu verzapfen, oder?

(Übrigens hab ich selbst große Einwände gegen die Verwendung von typDatasets als Viewmodel: Der Xaml-Editor bietet keinerlei Unterstützung beim Binden an typDatarows.)

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

Also neu für mich war, dass du ganz unbefangen auch an Model-Klassen bindest. Ich bin bislang immer vom MVVM-Puristen-Dogma ausgegangen, dass jede Model-Klasse in eine Viewmodel-Klasse konvertiert werden muss, sonst darf Xaml nicht dran binden (oder es ist kein MVVM).

Zwei Sachen dazu.

  1. Ich binde NICHT das Model. Gebunden ist das, was im DataContext steht. Die gebundenen Elemente des Views haben zwar einen Path auf eine Property, die u.a. das Modell sein kann, aber gebunden ist ausschließlich das ViewModel. Der View hat zur Laufzeit ausschließlich eine Referenz auf das ViewModel, und das ist, worauf es ankommt. Nochmal: "gebunden an" bedeutet, dass (zur Laufzeit) eine Referenz auf eine konkrete Instanz einer Klasse da ist. Ich glaube, dass die Missverständnisse im Bezug auf MVVM zu weiten Teilen einem Missverständnis eben dieses Sachverhaltes geschuldet sind. CategoryViewModel kann es nur geben, wenn im View irgendwo ein "<Control.DataContext><CategoryViewModel /></Control.DataContext>" o.ä. gibt. Ansonsten ist es kein ViewModel.

  2. Ich weiss nicht, wie du das siehst, aber ich neige dazu, die Definition von Microsoft als MVVM-Purismus zu interpretieren. Liegt irgendwie nahe 😉. Und Microsoft bezeichnet den Fall, dass ein ViewModel die Properties des Models wrappt, weil dieses zB kein INotifyPropertyChanged implementiert, ausdrücklich als Ausnahme, also eben NICHT als pures MVVM. Und das würde ich auch nicht zur Diskussion stellen. Ein POCO als Modell ist ein Sonderfall von MVVM, und nicht die Standardimplementierung.

(DataSet-Diskussion lass ich mal weg, bringt hier nicht viel*...jeder, wie er happy is 😉

Ganz allgemein halte ich die Trennung zwischen View und ViewModel, den Verzicht auf Code-Behind und das Binden per XAML aber für absolut wichtigere Bestandteile einer MVVM-Implementierung. Die Trennung zwischen Model und VM ist nicht ganz so starr vorgebenen. WPF erzwingt ja schon saubere Views durch das XAML-Geraffel (und weicht das wieder auf mit Code-Behind^^), daher bietet sich MVVM halt an, wenn man WPF macht. Wie das Modell aussehen sollte, ist nicht wirklich festgelegt bis auf einige Fälle, in denen in der MSDN eben auf den "Ausnahmefall" POCO verwiesen wird, woraus man seine Schlüsse ziehen kann, wie das Modell eigentlich aussehen kann.

LaTino

  • ich halte DataTables für ein Konstrukt, das nur existiert, weil man die Daten, die in einem DataGridView unter Windows.Forms dargestellt werden, irgendwie modellieren wollte. Entsprechend hadere ich auch mit dem DataGrid in WPF, weil das die Designsünden vom DataGridView wieder in die WPF schleift...aber sei's drum.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.299 Beiträge seit 2008
vor 7 Jahren

Ich binde NICHT das Model. Gebunden ist das, was im DataContext steht. Die gebundenen Elemente des Views haben zwar einen Path auf eine Property, die u.a. das Modell sein kann, aber gebunden ist ausschließlich das ViewModel. Guck - wieder eine Ansichtsweise, die mir neu ist.
Ich hätte immer gesagt: Gebunden ist, wo {Binding ...} steht, und was darin steht, daran ist gebunden.

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

So funktioniert das Binding in Windows.Forms, nicht das von WPF.


myTextBox.DataBindings.Add("Text", _controller, "DisplayText"); //bindet den _controller
myTextBox.DataBindings.Add("Text", _controller.SubProperty, "Text"); //bindet die Instanz von SubProperty
myTextBox.DataBindings.Add("Text", _controller, "SubProperty.Text"); //geht nicht

Dabei ist die dritte Variante die, nach der WPF vorgeht. Gebunden wird aber, das sieht man in den drei Beispielen ganz gut, an den zweiten Parameter der Add-Methode, und NICHT an den Pfad.

Und exakt das macht WPF auch.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)