none
Datagridview im Datarepeater filtern RRS feed

  • Frage

  • Ich benötige Hilfe beim Filtern von Datensätzen eines Datagridview, das sich auf einem Datarepeater befindet.

    Mein Ziel ist, dass auf Knopfdruck sämtliche Datagridviews gefiltert werden. Änderungen am Datagridview müssen in der ursprünglichen (autoHändler) Liste erscheinen.

    Die Bindingsource wird zwar gefiltert allerdings werden die Datagridviews nicht aktualisiert! Wie mache ich das?

    Hier mein Ansatz:

    Imports System.ComponentModel
    Imports System.Reflection
    
    Public Class Form1
    
        Private autoListe1 As New BindingList(Of Auto)
        Private autoListe2 As New BindingList(Of Auto)
        Private autohaendler As New List(Of Haendler)
        Private bs As BindingSource
        Private view As DataView
        Private filterText As String
    
        Private sortColName As String
        Private sortDirection As ListSortDirection
    
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
            Dim a1 As New Auto With {.Speed = 120, .Marke = "VW", .Ps = 125}
            Dim a2 As New Auto With {.Speed = 280, .Marke = "BMW", .Ps = 100}
            Dim a3 As New Auto With {.Speed = 157, .Marke = "Mazda", .Ps = 150}
            Dim a4 As New Auto With {.Speed = 111, .Marke = "Audi", .Ps = 250}
            Dim a5 As New Auto With {.Speed = 184, .Marke = "Peugeot", .Ps = 100}
            Dim a6 As New Auto With {.Speed = 150, .Marke = "Mercedes", .Ps = 200}
            Dim a7 As New Auto With {.Speed = 128, .Marke = "Renault", .Ps = 180}
    
            autoListe1.Add(a1)
            autoListe1.Add(a2)
            autoListe1.Add(a3)
            autoListe1.Add(a4)
            autoListe1.Add(a5)
            autoListe1.Add(a6)
            autoListe1.Add(a7)
    
            Dim a8 As New Auto With {.Speed = 120, .Marke = "Peugeot", .Ps = 125}
            Dim a9 As New Auto With {.Speed = 280, .Marke = "Lada", .Ps = 100}
            Dim a10 As New Auto With {.Speed = 157, .Marke = "Ferrari", .Ps = 150}
            Dim a11 As New Auto With {.Speed = 111, .Marke = "Audi", .Ps = 250}
    
            autoListe2.Add(a8)
            autoListe2.Add(a9)
            autoListe2.Add(a10)
            autoListe2.Add(a11)
    
            Dim h1 As New Haendler With {.Name = "Autokauf GmbH", .Wagen = autoListe1}
            Dim h2 As New Haendler With {.Name = "Achmed und Ali Auto an -und verkauf", .Wagen = autoListe2}
    
            autohaendler.Add(h1)
            autohaendler.Add(h2)
    
            BindingSource1.DataSource = autohaendler
            DataRepeater1.DataSource = BindingSource1
        End Sub
    
        Private Sub DataRepeater1_DrawItem(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs) Handles DataRepeater1.DrawItem
            Dim lbl As Label
            lbl = CType(e.DataRepeaterItem.Controls("Label1"), Label)
            lbl.Text = Me.autohaendler.Item(e.DataRepeaterItem.ItemIndex).Name
    
            Dim dgv As DataGridView
            dgv = CType(e.DataRepeaterItem.Controls("DataGridView1"), DataGridView)
    
            If dgv.DataSource Is Nothing Then
                'Bindingsource mit Daten füllen und ans Datagridview binden
                bs = New BindingSource()
                bs.DataSource = Me.autohaendler.Item(e.DataRepeaterItem.ItemIndex).Wagen
    
                dgv.DataSource = bs
            End If
    
            Dim dgvBindingSource As Object
            dgvBindingSource = dgv.DataSource
    
            dgv.EndEdit()
            Filter(CType(dgvBindingSource, BindingSource))
        End Sub
    
        Private Sub Filter(ByVal _bs As BindingSource)
            _bs.EndEdit()
            _bs.Filter = filterText
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            filterText = "Marke like 'P%'"
            RefreshRepeaterItems()
        End Sub
    
        Private Sub RefreshRepeaterItems()
            'workaround zum aktualisieren aller Repeater Items
            Dim size As Size = DataRepeater1.Size
            Dim sizeBigger As Size = New Size(size.Width, size.Height + 1)
            DataRepeater1.Size = sizeBigger
            DataRepeater1.Size = size
        End Sub
    
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            'Wagen ausgeben um Änderungen anzuzeigen
            For Each haendler In autohaendler
                For Each wagen In haendler.Wagen
                    Console.WriteLine(wagen.Marke.ToString)
                Next
            Next
        End Sub
    End Class
    

    Dienstag, 23. April 2013 08:07

Alle Antworten

  • Hallo Jan,

    die BindingSource unterstützt zwar Filterung nicht aber die BindingList. Daher wirst du nicht drumherum kommen, die Filterfunktion selbst zu implementieren. Um das Rad nicht neu erfinden zu müssen, kannst du in deinem Project auch die FilterableBindingList(Of T) von hier verwenden. Anstelle von BindingList(Of Auto) verwendest du einfach FilterableBindingList(Of Auto) in deinem Code.

    Gruß,

    LBB

    Dienstag, 23. April 2013 09:56
  • Hallo LBB,

    ich habe die FilterableBindingList(of T) implementiert. Die Filterung funktioniert..
    ..aber, folgende Sachen stören mich:

    • Die Filterung findet nicht nur auf der Oberfläche statt, sondern direkt in der Liste. In der Liste werden also nur noch die sichtbaren Elemente aufgeführt.
    • Filter wie "Marke like M%" oder "Marke = VW or Marke = BMW" funktionieren nicht.

    Gibt es noch andere Möglichkeiten oder lässt sich die FilterableBindingList so modifizieren, dass auch Mehrfach Filterausdrücke möglich sind?

    Ich habe noch eine andere Möglichkeit gefunden die Daten zu filtern: Die Verwendung einer DataTable.

    Im DrawItem Event habe ich dazu die Liste in eine DataTable konvertiert und an die BindingListe gebunden.

    If dgv.DataSource Is Nothing Then
    
                bsPasser = New BindingSource
                 bsPasser.DataSource = (ToDataTable(Me.bilanzListe.Item(e.DataRepeaterItem.ItemIndex).BilanzPasser))
                dgv.DataSource = bsPasser
    
    End If
    Problem hierbei ist, dass Änderungen im Datagridview nicht in der Autohändler Liste erscheinen?!

     

    Dienstag, 23. April 2013 12:05
  • Hallo Jan,

    du kannst es auch mit der BindingListView probieren.

    Gruss,

    LBB

    Dienstag, 30. April 2013 09:57