DataBinding zwischen Klasseneigeschaften und/oder BindingSource?

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von cl10k.

    DataBinding zwischen Klasseneigeschaften und/oder BindingSource?

    Nabend,


    ich habe eine BindingSource (Datatable) durch die ich mittels Combobox navigiere. An der Bindingsource hängen per DataBinding mehrere Labels für die anderen Spalten des Tables.

    Jetzt habe ich allerdings noch einen Haufen Datenklassen mit Properties, die gefüllt werden möchten. Leider kann ich diese Properties nicht mehr an die Labels binden da dann ein doppeltes DataBinding an den Controls hängen würde (klar!). Ich habe mir den ganzen Tag schon die Finder wund gegoogelt ob man die Datenklassen-Properties auch direkt an das Bindingsource binden kann - aber leider vergebens.

    Gibt es einen eleganten Weg wie ich aus der Bindingsource gleichzeitig meine Controls und meine Datenklassen befüllen kann?
    Puuuh was für ein radikaler Vorschlag! Ich habe fast ein Jahr täglich Vollzeit an dem Programm gearbeitet - davon wäre dann ne Menge für die Katz.

    Ich kann so spontan die Konsequenzen eines solchen Schrittes gar nicht überschauen. Mein Chef erwartet in 3 Monaten ein Ergebnis (inkl Dokumentation)...

    Mal ganz willkürlich einige wenige Aspekte herausgegriffen: Mein Programm behandelt ein komplexes technisches System (Raketen...) mit über 20 Teilsystemen und jeweils dutzenden Properties. All diese Teilsysteme wechselwirken stark miteinander und können flexibel konfiguriert werden - das müsste alles neu umgesetzt werden.

    Ich finde den Gedanken schon reizvoll, zumal ich mir gut vorstellen kann, wenn man das Konzept konsequent durchzieht, kann man sich ne Menge Arbeit ersparen und einige Probleme sehr konsistent und elegant lösen. Aber jetzt nochmal umspringen führt mich in den Abgrund!

    Hast du nicht evtl einen Vorschlag für die eigentliche Fragestellung der deutlich weniger radikal ist und nicht meinen Kopf kostet :S ?
    Ich habe jetzt mal ein Buch zum Thema Datenbanken bestellt um ein bisschen mehr Material zu Recherche zu haben. Bis der Schinken hier ist, möchte ich nicht ganz untätig sein und habe mich versuchshalber mal daran gesetzt eine meiner einfacheren Datenklassen im Dataset nachzustellen.

    Einfachere Aspekte funktionieren sogar ganz ok, trotzdem bleiben Fragen zur richtigen Modellierung (google ist zumindestens bei dieser speziellen Frage nicht so wahnsinnig hilfreich):

    In meiner ursprünglichen Datenklasse sind fast alle numerischen Properties wiederum eigene kleine Klassen, welche dann jeweils den eigentlichen Wert und dessen Grenzen aufnehmen.

    BSP: Für die Datenklasse Zylinder könnte ich dann Zylinder.Durchmesser.Wert / Zylinder.Durchmesser.obereGrenze / Zylinder.Durchmesser.untereGrenze ansprechen und weiterverarbeiten


    Wie überträgt man das in eine Tabellenbeziehung?
    Bilder
    • xxxxxxxxxxxx.PNG

      7,81 kB, 444×186, 182 mal angesehen
    mir fällt grad ein, bindingSource kann auch an gecodete Klassen binden.
    Verwende ich halt sogutwienie, weil selbstgecodetes kann keine m:n - Relationen modellieren. Auch zickt das glaub noch mehr rum, wenn man die Klassen ändert, was man ja andauernd tut.
    Nur Mischen geht halt nicht. Also optimal wäreja, man könnte an eine DataTable binden, und dann inne partiale Klasse da noch superintelligente Properties zusätzlich dranmachen. Aber - haste glaub selbst gemerkt - selbstgebastelte Properties erkennt die BindingSource nicht.

    Was dir sicherlich total gut entgegenkäme ist das Binding-System von Wpf.

    aber Wpf ist nicht einfach.

    Ich muß aber auch sagen, dassich deine Frage hier nicht sonderlich verstanden habe. Aus BindingSource Controls und Datenklassen befüllen??
    BindingSources sind Zwischenglieder zw. Datenklassen und Controls, und Befüllen ist bei Databinding eher der falsche Begriff.
    Befüllen tut man eine Auflistung von Datensätzen (Datenklassen), und daran ist Databinding ühaupt nicht beteiligt, also nicht die BindingSources und erst recht nicht die Controls.
    Im Falle Dataset ist die Auflistung eine DataTable, die befüllt wird.

    Ich kann auch mal probieren, ob ich einer DataTable eine selbstgebastelte Klasse als spaltentyp andrehen kann - mit System.Drawing.Rectangle habichs ja schon gemacht.
    Im DGV ist sone Property aber dann nurnoch darstellbar, wenns einen sehr guten TypConverter für die Datenklasse gibt.
    Aber du willst die garnet im DGV editieren, odr?

    Ich bin auch nicht mehr sicher, ob Dataset auch für deine Rakete so viel bringt, denn dein Proggi verarbeitet ja keine Tabelle von Raketen, sondern nur eine einzige.
    Moin, konkret sieht mein Problem so aus:

    Ich habe ein separates kleines Form UND eine Klasse Material welche ich mit einem Datensatz aus einer DataTable befüllen möchte.

    Der User wählt den entsprechenden Datensatz durch eine ComboBox aus, die Labels auf dem Form werden ganz konventionell an die BindingSource der ComboBox gebunden und zeigen den Datensatz auch korrekt an.

    Nur wie kriege ich diesen Datensatz auch in meine Materialklasse? Der generell von mir genutzte Weg aus DataBinding zwischen Control und Klasse funktioniert hier scheinbar nicht.


    Ein DGV oder gar das Editieren des Datatable ist an dieser Stelle nicht gefordert! Ich möchte einfach nur einen Datensatz auslesen, in meine Klasseneigenschaften schreiben und parallel dazu anzeigen...
    Bilder
    • CmbBx.PNG

      83,91 kB, 1.029×772, 196 mal angesehen
    • Materialklasse.png

      37,27 kB, 833×409, 158 mal angesehen
    • datatable.PNG

      7,59 kB, 172×255, 144 mal angesehen

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „cl10k“ ()

    Nabend,


    Ich modelliere meine Rakete in einer (selbst erstellten) Klassenstruktur. Dementsprechend landet der gesamte Userinput (nach Validierung) und daraus abgeleitete Größen in dieser Struktur in einer jeweils passenden Property . Mein Datatable hält einfach nur bestimmte Materialien bereit und dient quasi ebenfalls, nach Auswahl eines Datensatzes mittels Combobox, als weiterer Input für die Klassenstruktur.

    Ist der Gedanke so absurd? Ich denke dabei vor allem an die Leute (Programmierlaien so wie ich) die irgendwann mal das Programm erweitern sollen. Da werden dann vor allem Exporter für unsere anderen Tools benötigt. Solange man konsequent der Klassenstruktur folgt (Intellisense hilft ja dabei) findet man jede gesuchte Größe an einem Ort der vom logischen Aufbau her ziemlich gut der Realität entspricht:

    z.B. Rocket.Hull.Material.Density für die Dichte des gewählten Hüllenmaterials oder Rocket.UpperInterstage.OuterDiameter für den Durchmesser des Stufenadapters.


    EDIT: Ich schätze mal du wolltest mit deiner Anmerkung zur Redundanz darauf hinaus, dass ich in meiner Materialklasse nur den Verweis auf den durch die Combobox markierten Datensatz des DataTable setze, oder? Ich habe es stundenlang vergeblich versucht (Frust!). Ich kann, wenn die Combobox bereits an einer Bindingsource hängt, nichts anderes daran binden (besser gesagt, ich kriege es nicht hin).

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „cl10k“ ()

    cl10k schrieb:

    Ich schätze mal du wolltest mit deiner Anmerkung zur Redundanz darauf hinaus, dass ich in meiner Materialklasse nur den Verweis auf den durch die Combobox markierten Datensatz des DataTable setze, oder?
    Nein.
    Redundanz ist einfach böse. Immer.
    Es darf nur ein Datenmodell geben, und auch fürs Material - nur ein Datenmodell. Und da dein Datenmodell auf selbstgebastelten Klassen aufbaut, scheint mir höchstwahrscheinlich, dass entweder deine MaterialKlasse, oder aber deine MaterialDataTable besser abgeschafft gehört.

    Ansonsten ists durchaus denkbar, auch mit selbstgebastelten Klassen Wirklichkeit zu modellieren. Selbstgebastelte Klassen können halt keine m:n - Relationen modellieren, dassis deren prinzipielle Einschränkung.
    Und dann muß man halt vieles zu Fuß machen, was bei DataTable von vornherein mit eingebaut ist.

    Selbstgebastelte Klassen haben sogar einige Vorzüge vor DataRows, zB. können sie u.U. auch vererbt werden (falls man das braucht), unterstützen ganz problemlos die absonderlichsten Datentypen, und sind beliebig um weitere (auch beliebig intelligente) Properties erweiterbar, wo man bei DataRow nur eine vergleichsweise "dumme" DataColumn zufügen kann.

    Dein Combobox-Problem kannichnich ganz nachvollziehen - kannst du mal ein Testprojekt machen, dann kannich eine Combo da mal verknüpfen versuchen.

    Prinzipiell funzt Databinding auch mit allen anneren Klassen und deren Properties, nur zum Mischen ist BindingSource zu doof. Also wenn eine typDataTable Datasource ist, erkennt BindingSource nur die richtigen Spalten (DataColumns) als bindebare Property.
    Anbei nun ein Testprojekt: Ich habe im Kleinen mal nachgestellt, wie die typischen Funktionen meines Programmes aussehen.

    DataBinding habe ich dabei weitgehend von Hand gemacht. Auf Schnickschnack wie Validierung, etc habe ich verzichtet. Im Debug-Output kann man die Weitergabe der Eingaben nachverfolgen...

    Ziel ist es alle Nutzereingaben in der Klassenstruktur Hull.xyz zu speichern. Dementsprechend muss irgendwie auch gespeichert werden, welcher Datensatz denn nun vom User für das Material ausgewählt wurde. Ich hoffe das Beispiel ist einfach genug gehalten.
    Dateien
    Vielen Dank! :) Wenigstens kann ich jetzt abspeichern welches Material gewählt wurde - das hilft mir wirklich sehr weiter!


    Zwei Fragen bleiben:

    Warum hast du die Labels in diesem kleinen weißen Detailpanel durch Textboxen ersetzt?

    richtig was gutes habich auch nicht gefunden - halt bindingSource-CurrentChanged-Event verarbeiten


    Ist mein Vorgehen so unüblich das es dafür keine konventionelle Lösung gibt?

    lg

    cl10k schrieb:

    Warum hast du die Labels in diesem kleinen weißen Detailpanel durch Textboxen ersetzt?
    ich habs Binding im Designer eingerichtet, und nicht drauf geachtet, dasses vorher Labels waren.

    cl10k schrieb:

    Ist mein Vorgehen so unüblich das es dafür keine konventionelle Lösung gibt?
    also insgesamt findich das teil schon ziemlich exotisch:
    eine Datenverarbeitung für nur einen Datensatz.
    Der Datensatz ist durch eine selbstgebastelte Klasse modelliert.
    die Klasse ist aber einer normalen DataTable (Material) relational untergeordnet, die viele Materialien auswählbar macht, und die aus einer Datei geladen, und wohl auch abgespeichert wird.
    Der eigentliche, einzige Datensatz wird nicht geladen oder abgespeichert.


    Aber hat mit dem Combo-Problem nicht soo viel zu tun.
    Das Prob ist: Eigentlich kann man auch normal binden, aber der OnPropertyChanged-Trigger reagiert bei der Combobox nicht, sodass du die Combo immer erst verlassen mußt, damit das Databinding den neuen Wert übernimmt.
    Der eigentliche, einzige Datensatz wird nicht geladen oder abgespeichert.


    Das liegt daran, dass dieser Datensatz nach Abschluss aller Eingaben an ein CAD-Programm weiter geschoben wird. Ziel dieses ganzen Unterfangen, ist es ein parametrisches 3D-Modell zu verändern und dann daran Messungen durchzuführen.

    Aber hat mit dem Combo-Problem nicht soo viel zu tun.
    Das Prob ist: Eigentlich kann man auch normal binden, aber der OnPropertyChanged-Trigger reagiert bei der Combobox nicht, sodass du die Combo immer erst verlassen mußt, damit das Databinding den neuen Wert übernimmt.


    Ich hoffe ich nerve dich noch nicht, aber kannst du dazu nochmal etwas schreiben. An welche Property hänge ich mich denn in diesem Fall?
    Naja du schreibst das generell ein Binding an die ComboBox schon möglich wäre, dann aber OnPropertyChanged nicht funktionieren würde - und genau das habe ich gestern x Stunden versucht:

    Mich an irgendeine Property von ComboBox zu hängen und von dort dann (über Umwege) die DataRow abzugreifen.


    Mir kam dabei immer in die Quere, dass die ComboBox bereits an dem Bindingsource hängt. Ganz übel finde ich auch, mit welchen Fehlermeldungen dann der Debugger kommt. Bisher konnte ich trotz Break bei Common Language Runtime Exceptions nie so richtig nachvollziehen was es denn nun gerade an einem Binding zu meckern gab.
    achso. du musst das Combobox.SelectedItem an cls_HullBindingSource.Material hängen.

    achnee - ist noch komplizierter: in einer am Dataset hängenden BindingSource sind DataRowViews drin, keine Datarows. Daher bräuchte die cls_Hull eine zusätzliche Property As DataRowView, damit sie zum Binding Kompatibel ist.
    also ist umständlicher und weniger leistungsfähig, als wenn mans per event macht.
    Dateien