Fragensteller
Datagridview im Datarepeater filtern

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
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
- Bearbeitet LittleBlueBird Dienstag, 23. April 2013 10:15
-
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?! -