Dataset m:n-View Darstellung in nur 2 DGV‘s

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 32 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Hofi1609 schrieb:

    Wie oben beschrieben, möchte ich die Inhalte der einzelnen Tabellen als DGV und im Detail mit Textfeldern etc. darstellen. Dabei sollen die DGVs zum Navigieren dienen.

    Das war die Antwort.
    Im Prinzip nichts anderes wie in Video 4 nur, dass mein Datenmodell etwas komplexer ist.

    Aber wie im vorhergehendem Post beschrieben, liegt mein Problem bei den Bindigins von File2db zu FileData und dem Rest der rechts davon steht.

    Zum besseren Verständnis hier nochmal das komplette DataSet:


    Die roten Pfeile zeigen die Reihenfolge der Daten, rot eingerahmtes wird bei der Darstellung zusammengefasst und alles in grün, da liegt mein Problem.

    Hier mal ein nicht fertiger Entwurf der Oberfläche:


    Links die Serien, dann die Staffeln anschließend die Episoden, unten immer das DGV und oben die Details. Bis hier her funktioniert die Sache einwandfrei.
    Rechts sind dann die FileDaten mit allen dazugehörigen Metadaten, hier ist die Darstellung noch gemischt aus DGVs und Details.
    Einige Sachen habe ich auch nur für die Entwicklung auf die Oberfläche gelegt, die fallen später wieder weg oder werden anders dargestellt.

    Ich hoffe jetzt ist es verständlicher

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

    ähm - nicht wirklich.
    Aber weil Vaporized die Tabellen nochmal die Tabellen Cut und Eit in die Diskussion bringt reime ich mir mal folgendes zusammen:
    Du möchtest, wenn jemand einen File2DB-Datensatz anwählt, dass dann die Anzeige zB der Eit-Tabelle umspringt auf die Child-Datensätze derjenigen FileRow, auf welche der Fremdschlüssel der angewählten File2DbRow verweist?
    Ist das richtig?
    Also wenns das ist, muss man bisserl UserCode schreiben - nur mit Databinding geht das nimmeh.
    Nämlich du kannst eine zweite File-BindingSource aufs Form tun, quasi "Unsichtbar", nämlich kein Control ist daran gebunden. Aber über die File_Eit-Relation ist eine Eit-BindingSource dran gebunden. Also ein ParentChildView "File->Eit" mit unsichtbarem Parent.
    Und den unsichtbaren Parent kannste per Code anwählen, indem du im File2db-BindingSource.CurrentChanged-Event File-BindingSource.Position festlegst.

    Ach übrigens: deine Benamung hat ein starkes Vereinfachungs-Potential. Meine Wenigkeit lässt wie du siehst unnütze Prefixe und Postfixe (wie 'sm', 'Data') einfach weg.
    Dadurch wird meine Sprache einfacher verständlich, und das obwohl ich nichtmal die richtigen Namen verwende.
    Um wieviel einfacher verständlich würde dein Code erst werden, wenn du die unnützen Prefixe und Postfixe mal wirklich aus deinem Datenmodell entferntest!

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    @ErfinderDesRades Vielen Dank für deine Tipps, jetzt haben wir uns verstanden :thumbsup:

    Ich werde deine Vorschläge mal ausprobieren, mal sehen ob ich es hin bekomme.

    Ich hatte gestern noch einen anderen Weg begonnen:
    Eine FileDataBindingSource erstellt und direkt an das DataSet gebunden und dann im DGV File2db SelectionChanged die ausgewählte File ID ermittelt und damit einen Filter auf die FileDataBindingSource gesetzt. Das scheint ebenfalls zu funktionieren muss aber die anderen Tabellen noch anbinden. Nur ist der Syntax für den Filter wohl nicht mehr typisiert ;)

    ErfinderDesRades schrieb:

    Ach übrigens: deine Benamung hat ein starkes Vereinfachungs-Potential. Meine Wenigkeit lässt wie du siehst unnütze Prefixe und Postfixe (wie 'sm', 'Data') einfach weg.
    Dadurch wird meine Sprache einfacher verständlich, und das obwohl ich nichtmal die richtigen Namen verwende.
    Um wieviel einfacher verständlich würde dein Code erst werden, wenn du die unnützen Prefixe und Postfixe mal wirklich aus deinem Datenmodell entferntest!

    Hier hast du natürlich recht! Ist wohl noch eine alte dumme Angewohnheit von dBase/Clipper als es noch keine Objekte gab, werd mich bemühen das in Zukunft zu unterlassen :thumbup:
    Jo, dein Verfahren hat dieselbe Wirkung wie mein Vorschlag, nur ich würde kein DGV-Event verarbeiten, wenn ich auch ein BindingSource-Event verarbeiten kann.
    Ist eine Art Prinzip: Immer möglichst nah an den Daten die Daten verarbeiten (aber zur Not gehe ich auch an DGVs ran).
    Und statt eines Filters führe ich eine Suche inne BindingSource durch, und setze dann nur ihre Position - anstatt mittels Filter da einen Index neu aufzubauen.
    Ist wohl irrelevant, das eine geht so gut wie's andere.
    Es gibt auch bereits eine BindingSource-Suche, nämlich bs.Find().
    Aber vor langem fand ich die buggy - heutzutage widerspricht mir Vaporized darin.

    Wie dem auch sei - hier Auszug meiner Helperleins:

    VB.NET-Quellcode

    1. ''' <summary> returnt die typisierte Datarow an aktueller Position - oder Nothing. </summary>
    2. <Extension()>
    3. Public Function At(Of T As DataRow)(bs As BindingSource) As T
    4. Return DirectCast(bs.At(bs.Position), T)
    5. End Function
    6. ''' <summary>returnt die typisierte Datarow am index. Bei ungültigem index Nothing (keine OutOfRange-Exception!)</summary>
    7. <Extension()>
    8. Public Function At(Of T As DataRow)(bs As BindingSource, index As Integer) As T
    9. Return DirectCast(bs.At(index), T)
    10. End Function
    11. ''' <summary> returnt die untypisierte Datarow an aktueller Position. </summary>
    12. <Extension()>
    13. Public Function At(bs As BindingSource) As DataRow
    14. Return bs.At(bs.Position)
    15. End Function
    16. ''' <summary>returnt die untypisierte Datarow am index. Bei ungültigem index Nothing (keine OutOfRange-Exception!)</summary>
    17. <Extension()>
    18. Public Function At(bs As BindingSource, index As Integer) As DataRow
    19. If index < 0 OrElse index >= bs.Count Then Return Nothing
    20. Return DirectCast(bs(index), DataRowView).Row
    21. End Function
    22. '''' <summary> stellt die angegebene DataRow ein </summary>
    23. <Extension()>
    24. Public Function MoveToRow(bs As BindingSource, row As DataRow) As Boolean
    25. If row Is bs.At Then Return True
    26. If bs.IsBindingSuspended Then Return False
    27. Dim dv = DirectCast(bs.List, DataView)
    28. For i As Integer = 0 To bs.Count - 1
    29. If dv(i).Row Is row Then
    30. bs.CancelEdit() 'ansonsten setzter u.U. beim Moven die vorherige Row auf Rowstate.Changed
    31. bs.Position = i
    32. Return True
    33. End If
    34. Next
    35. Return False
    36. End Function


    In kombination so Aufzurufen müsste tun was soll:

    VB.NET-Quellcode

    1. bsFile.MoveToRow(bsFile2Db.At())

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

    Ich hab es mit meiner (modifizierten) Lösung nun hinbekommen (siehe unten).

    Deine @ErfinderDesRades Lösung (nochmals danke für die Unterstützung) hab ich zwar fehlerfrei zum laufen bekommen, hat aber leider nicht das gewünschte Ergebnis erbracht.
    Entweder habe ich deine Ausführung nicht richtig verstanden oder wir missverstehen uns immer noch ;) weil mich deine Lösung aber interessiert, werde ich nochmal versuchen das detailliert zu erklären.

    Wir betrachten hier nur 3 Tabellen:
    1. Episoden, hier ist nur die Schlüsselspalte ID von Interesse.
    2. File2db, ist eine Hilfstabelle, welche in der GUI nicht wirklich angezeigt werden soll. Hier benötigen wir die 2 Fremdschlüsselspalten EPID und FIID.
    2. Files, hier wird ebenfalls nur die Schlüsselspalte ID betrachtet

    Im Dataset besteht eine 1:n Beziehung zwischen Episoden.ID und File2db.EPID und eine weitere 1:n Beziehung zwischen File.ID und File2db.FIID.
    Außerdem (und das ist entscheidend) bestehen noch mehrere 1:n Beziehungen von File.ID zu weitern Tabellen, welche für unsere Betrachtung aber keine Rolle spielen. Nur die Beziehungen müssen beachtet werden.

    Die Tabelle Episoden ist über die Bindingsource bsEpisoden an ein dgvEpisoden gebunden.
    Die Tabelle File2db ist über die Bindingsource bsEpisoden_File2db an ein dgvFile gebunden, in der ich über JoinView die Daten von File anzeige.
    Die Tabelle File ist über die Bindingsource bsFile an einzelne Textboxen gebunden.

    Im dgvFile werden mir nun alle Dateien zur ausgewählten Episode korrekt angezeigt, aber eine Veränderung der Auswahl hier, hat keine Auswirkungen auf die bsFile!
    Das heißt ich bekomme weder in den mit bsFile gebundenen Textboxen noch in den oben genannten Folgetabellen eine korrekte Anzeige.

    Laut deinem Vorschlag soll ja nun die Position einer Bindingsource auf die bsFile übertragen werden, nur leider finde ich keine Bindingsource welche eine aktuelle Position für die Auswahl im dgbFiles hat.

    VB.NET-Quellcode

    1. ​bsFile.MoveToRow(???.AT())


    Was müsste ich für die 3 Fragezeichen einsetzen?

    Nun zu meiner Lösung:

    Vorab mein weiter oben genannter Ansatz mit dem Filter auf bsFile hat zwar funktioniert, aber wenn im dgvFileData mehr als ein Resultat stand, konnten die Daten nur für die momentan ausgewählte Zeile angezeigt werden, die anderen Zeilen blieben leer.

    Ich habe nun anstatt bsFile.Filter die Funktion bsFile.Find benutzt und den Code in den Event dgvFile.SelectionChanged geschrieben. Somit führt eine Änderung der Auswahl im dgvFile auch zu einer korrekten Positionsänderung in bsFile.

    VB.NET-Quellcode

    1. Private Sub dgvFile_SelectionChanged(sender As Object, e As EventArgs) Handles dgvFile.SelectionChanged
    2. Dim iID, iPos As Integer
    3. If IsNothing(dgvFile.CurrentRow) Then Exit Sub
    4. iID = dgvFile.CurrentRow.Cells(0).Value
    5. lfdID.Text = iID
    6. iPos = bsFile.Find("fd_ID", iID)
    7. bsFile.Position = iPos
    8. End Sub


    Leider sieht das nicht sehr typisiert aus :( oder hast du noch eine bessere Lösung?

    VB.NET-Quellcode

    1. bsFile.MoveToRow(bsFile2Db.AT(Of File2DbRow).FileRow)




    Hofi1609 schrieb:

    Leider sieht das nicht sehr typisiert aus
    Wohl wahr.
    Das sieht sogar aus, also ob da jemand Option Strict Off programmiert.

    Ganz wichtig: Visual Studio - Empfohlene Einstellungen
    Richte deine Entwicklungsumgebung so ein, dass vb.net eine vollwertige objektorientierte Sprache ist.
    Andernfalls programmierst du nur einen Krepel-vb6-Dialekt, und lernst es möglicherweise nie richtig.

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

    ErfinderDesRades schrieb:

    VB.NET-Quellcode
    bsFile.MoveToRow(bsFile2Db.AT(Of File2DbRow).FileRow)


    Das geht leider nicht, File2dbRow erzeugt folgende Fehlermeldungen:
    "Overload resolution failed because no accessible accepts this number of type arguments" und "Type is not defined"

    Die Funktionen habe ich aus deinem Post weiter oben entnommen.


    ErfinderDesRades schrieb:


    Wohl wahr.
    Das sieht sogar aus, also ob da jemand Option Strict Off programmiert.


    Oh weh =O nun ist alles rot ;) viel Arbeit! Aber da ich mich ohnehin mit #C beschäftigen will ist das wohl eine gute Übung. Vorerst habe ich die Tipps aus dem Link befolgt, damit ich nun nicht tagelang Korrekturen machen muss.
    Ich werde das Datei für Datei machen, so wie ich Zeit habe.

    Hier aber schon mal die erste Frage dazu:
    Wie substituiere ich IsEmpty, IsNothing, IsNumeric oder vbEmpty in ordentlichen .NET-Syntax?
    Die ist bereits definiert - in deinem Dataset.
    vermutlich fehlt dir sone Import-Anweisung:

    VB.NET-Quellcode

    1. Imports <MeineAnwendung.MeinDataset>
    Da ich diese Namen nicht weiss kann ichs nicht out of Box liefern
    Aber evtl. schlägt Intellisense das vor - da bin ich aber unsicher.

    Tatsache - Intellisense macht das:

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Es war Import SerienManager.dsSM1 - danke.
    Aber nun bekomme ich einen Fehler bei der Überladungsauflösung, da keine zugreifbare "At" diese Anzahl von Typargumenten akzeptiert.

    Ich habe da deinen Code aus Post 24 benutzt, kann es sein dass da noch was fehlt?
    Sollte es da nicht ne typisierte Überladung noch geben, in der Form .At(Of T)? Die fehlt in Post#24.
    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.