DGV mit BindingSource ohne Filter filtern

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

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

    DGV mit BindingSource ohne Filter filtern

    Hallo,

    ich wollte eine Zeile ausblenden in einem DGV das per BindingSource gebunden ist (Mit BS-Filter geht nicht). Genau diese BindingSource meckert aber gewaltig dabei rum. Genauer gesagt der CurrencyManager.
    (InvalidOperationException: Die mit der Position des Währungs-Managers verknüpfte Zeile kann nicht unsichtbar gemacht werden)
    Jetzt habe ich da bissel rumgekramt und es stellt sich raus, wenn ich die BindingSource vorübergehend abstöpsel, dann kann ich das machen.

    Ich möchte aber sichergehen, dass ich anschließend auch wieder alles richtig anschließe, denn ich weiß nicht was da wirklich mit meiner BindingSource passiert

    Muss ich sicherstellen, dass vor ResumeBinding alle Zeilen wieder sichtbar sind? (Händisch Visible wieder auf True stellen)
    Es scheint nämlich keine Fehlermeldung zu kommen, wenn ich das nicht mache. Sichtbar werden die Zeilen dennoch nicht, was paradox wirkt, weil nun ja genau das der Fall sein müsste, was die Exception betonte nicht erlaubt ist
    Auf der anderen Seite scheine ich mir das Sichtbarmachen sparen zu können, wenn ich einfach ResetBindings aufrufe, denn dann werden die Zeilen wieder sichtbar

    Version 1

    VB.NET-Quellcode

    1. Private Sub chkAusblenden_CheckedChanged(sender As Object, e As EventArgs) Handles chkAusblenden.CheckedChanged
    2. If chkAusblenden.Checked Then
    3. 'Andere Filteroptionen Disablen
    4. DtBindingSource.SuspendBinding()
    5. For i = 0 To dgv.Rows.Count - 1 Step 2
    6. dgv.Rows(i).Visible = False
    7. Next i
    8. Else
    9. For i = 0 To dgv.Rows.Count - 1 Step 2
    10. dgv.Rows(i).Visible = True
    11. Next i
    12. DtBindingSource.ResumeBinding()
    13. 'Andere Filteroptionen Enablen
    14. End If
    15. End Sub


    Version 2

    VB.NET-Quellcode

    1. Private Sub chkAusblenden_CheckedChanged(sender As Object, e As EventArgs) Handles chkAusblenden.CheckedChanged
    2. If chkAusblenden.Checked Then
    3. DtBindingSource.SuspendBinding()
    4. 'Andere Filteroptionen Disablen
    5. For i = 0 To dgv.Rows.Count - 1 Step 2
    6. dgv.Rows(i).Visible = False
    7. Next i
    8. Else
    9. DtBindingSource.ResumeBinding()
    10. DtBindingSource.ResetBindings()
    11. 'Andere Filteroptionen Enablen
    12. End If
    13. End Sub


    Tja also beides geht, einfacher ist natürlich unten, ich bin bei beidem nicht sicher, ob das so korrekt ist.
    Edit: Was ich auch festgestellt habe, wenn ich wieder Filter oder Sort Eigenschaften ändere, dann macht er auch schon wieder ganz vernünftig weiter und schmeißt alles was hintenrum gemacht wurde wieder raus (irgendwo scheint da ein ResetBindings sowieso zu laufen) also so wäre vielleicht auch vollkommen ausreichend:

    Version 3

    VB.NET-Quellcode

    1. Private Sub chkAusblenden_CheckedChanged(sender As Object, e As EventArgs) Handles chkAusblenden.CheckedChanged
    2. If chkAusblenden.Checked Then
    3. DtBindingSource.SuspendBinding()
    4. For i = 0 To dgv.Rows.Count - 1 Step 2
    5. dgv.Rows(i).Visible = False
    6. Next i
    7. End If
    8. End Sub


    Viele Grüße

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

    Haudruferzappeltnoch schrieb:

    Die mit der Position des Währungs-Managers verknüpfte Zeile kann nicht unsichtbar gemacht werden
    Du könntest versuchen, die Position des WährungsManagers (lautet die Exception wirklich so? meinGott!) auf eine Zeile zu setzen, die nicht unsichtbar gemacht wird.
    Also bindingSource.Position sinnvoll setzen.
    Wobei das problematisch sein kann, weil beim unsichtbar machen verschieben sich ja die Zeilen - wäre ich glatt neugierig, was nach soner Operation als BindingSource.Current bei rauskommt.

    Insgesamt ists wohl ein ziemlicher Eingriff ins BindungsSystem, die BS zu pausieren, und dieweil am Control rumzufummeln.
    Das muss man wohl anschliessend richtig wieder herstellen - machst du ja auch, in beiden Varianten.
    Die erste Variante scheint mir weniger "invasiv", während .ResetBinding die Binding-Situation komplett neu aufbaut. Damit liegste wohl eher auf der sicheren Seite, aber zB die CurrentPosition geht dabei verloren.
    Ach CurrencyManager hat mit der CurrentPosition zu tun? Dann ist die Übersetzung natürlich absolut irreführend.

    Ja, wenn ich vor dem Ausblenden eine Zeile anwähle, von der ich weiß das sie übrigbleibt, dann funktioniert das ohne SuspendBinding, da muss man erstmal drauf kommen wenn man sich fragt was die BindingSource mit Währungen zutun hat. 8|
    Direkt nach der Umstellung der Visisble Eigenschaften hat BindingSource.Current noch die richtige Zeile drin zumindest.

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

    Und was ist mit: In Deiner BS alle Daten haben und im DGV nur Teildaten anzeigen, indem dessen DataSource ne BindingSource ist, die mithilfe der 1. BS und Zusatz-Linq-Filtrierung nicht alles beinhaltet.
    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.
    Dann muss ich quasi umstöpseln zwischen diesen BSs? Die erste BindingSource wird abseits dieses merkwürdigen Filters ja auch normal genutzt.

    Ich würde die Current wohl setzen können. Aber ich muss wissen wie ich für meine BindingSource das Element richtig wähle. .Current sagt nur es sei ein Object. Wie krieg ich das raus?

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

    Das kann ich Dir nicht pauschal beantworten, da ich Dein Projekt nicht kenne.
    Da ich solch eine von mir vorgeschlagene Situation in einigen Projekten habe, hier nochmal mein Gedankengang:
    BS1 enthält alle Daten, indem es als DataSource ne DataTable oder ne List(Of DeinDatensatz) hat.
    Das DGV hat als DataSource aber BS2.
    BS2 wird per Code zu Beginn mit allen Daten aus BS1 gefüttert. Bei Bedarf wird aber noch was per LINQ vorher rausgefiltert. Als Beispiel:

    VB.NET-Quellcode

    1. BS2.DataSource = DeineDataTable.Select(Function(x) x.SollAngezeigtWerden).ToList
    Ob das für Dich anwendbar ist, entscheidet Dein Projekt(aufbau). Ansonsten kannst Du immer noch Deine Lösung hernehmen. Du hast ja eine ausgearbeitet. Welchen Sinn gibt es eigentlich in dem Ausblenden?
    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.

    Haudruferzappeltnoch schrieb:

    Ich würde die Current wohl setzen können.
    BS.Current ist ReadOnly.
    Ich sagte ja auch: BS.Position.
    Datasources zur Laufzeit umstöpseln, etwa von einer DataTable umschschwenken auf eine List(Of T) - da geht immer viel der Databinding-Leistungsfähigkeit flöten (etwa sortieren, zufügen, löschen im DGV).

    IMO Königsweg ist natürlich, der BS den richtigen Filter zu geben.
    Ansonsten finde ich das eiglich ganz witzig, und bemerkenswert, dass man datengebundene DGV-Zeilen offsichtlich problemlos verstecken kann.
    Aber was passiert, wenn ein Datensatz zb in einer sortierten Ansicht mitten drin eingefügt wird? Verschieben sich dann alle Datensätze, manche ins unsichtbare, andere werden sichtbar?
    @VaporiZed
    Das geht so tatsächlich nicht bei mir. Das ist nur ein temporäres Ausblenden und daher nicht vereinbar mit einem "vor dem Zuweisen filtern" denn das wäre ja permanent.

    Das DGV ist eine reine Übersicht, sie bietet Filteroptionen für die meisten Spalten, die alle von der BindingSource gehändelt werden können.
    Es werden bestimmte Zeilen farblich hinterlegt weil diese noch eine besondere Eigenschaft erfüllen, sie beinhalten Datensätze die sich in einer anderen Liste befinden.
    Die farbigen Zellen zu filtern geht nicht mit der BindingSource, weil mit der anderen Liste hat die ja nichts zutun.

    ErfinderDesRades schrieb:

    Aber was passiert, wenn ein Datensatz zb in einer sortierten Ansicht mitten drin eingefügt wird? Verschieben sich dann alle Datensätze, manche ins unsichtbare, andere werden sichtbar?
    Das ist bestimmt etwas wo man sich drüber Gedanken machen sollte, mein DGV ist zum Glück nicht editierbar. Ich bin froh, dass ich das nicht berükcksichtigen musste.
    Das hier funktioniert nun mit umgeschwenktem CurrencyManager:

    VB.NET-Quellcode

    1. Private Sub chkAusblenden_CheckedChanged(sender As Object, e As EventArgs) Handles chkAusblenden.CheckedChanged
    2. Dim dgvrow As DataGridViewRow
    3. Dim stopPositionChange As Boolean
    4. DtBindingSource.CurrencyManager.Position = dgv.Rows.Count - 1
    5. If chkAusblenden.Checked Then
    6. For i = 0 To dgv.Rows.Count - 1
    7. dgvrow = dgv.Rows(i)
    8. If condition Then
    9. If Not stopPositionChange Then DtBindingSource.CurrencyManager.Position = i : stopPositionChange = True
    10. Continue For
    11. End If
    12. dgvrow.Visible = False
    13. Next i
    14. Else
    15. For i = 0 To dgv.Rows.Count - 1
    16. dgvrow = dgv.Rows(i)
    17. If condition Then Continue For
    18. dgvrow.Visible = True
    19. Next i
    20. End If
    21. End Sub

    wobei ich die Checkbox noch Unchecke wenn die BindingSource wieder anderweitig angestoßen wird, weil das diesen Filter sofort wieder aufhebt.