SUPERCAT.DEV

Benvenut* sul mio blog

VB.NET

Filtrare una datagridview in VB.net su più colonne

27-06-2024

Filtri multipli sulle colonne che lavorano anche assieme

Imports System.Reflection

Public Class Form1

    Private _listaCompleta As List(Of RigaTabella)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        _listaCompleta = New List(Of RigaTabella) From
        {
          New RigaTabella With {.C1 = "AA", .C2 = 1, .C3 = Today().ToString("dd/MM/yyyy")},
          New RigaTabella With {.C1 = "BB", .C2 = 2, .C3 = Today().ToString("dd/MM/yyyy")},
          New RigaTabella With {.C1 = "CC", .C2 = 3, .C3 = Today().ToString("dd/MM/yyyy")},
          New RigaTabella With {.C1 = "CC", .C2 = 4, .C3 = Today().ToString("dd/MM/yyyy")},
          New RigaTabella With {.C1 = "DD", .C2 = 41, .C3 = "01/10/2024"},
          New RigaTabella With {.C1 = "DE", .C2 = 42, .C3 = "01/12/2024"},
          New RigaTabella With {.C1 = "DF", .C2 = 42, .C3 = "01/12/2025"},
          New RigaTabella With {.C1 = "EE", .C2 = 42, .C3 = "31/11/2025"}
        }

        For index As Integer = 1 To 5000
            _listaCompleta.Add(New RigaTabella With {.C1 = "E" + index.ToString, .C2 = index, .C3 = "01/01/" + index.ToString})
        Next

        dgv.DataSource = ConvertiInDataTable(_listaCompleta)
    End Sub

    Private Sub tbx_TextChanged(sender As Object, e As EventArgs) Handles tbxFiltro_C1.TextChanged, tbxFiltro_C2.TextChanged, tbxFiltro_C3.TextChanged
        Filtra(New RigaTabella() With {.C1 = tbxFiltro_C1.Text.ToLower, .C2 = tbxFiltro_C2.Text.ToLower, .C3 = tbxFiltro_C3.Text.ToLower})
    End Sub

    Private Sub Filtra(filtro As RigaTabella)
        If String.IsNullOrEmpty(filtro.C1) AndAlso String.IsNullOrEmpty(filtro.C2) AndAlso String.IsNullOrEmpty(filtro.C3) Then
            dgv.DataSource = ConvertiInDataTable(_listaCompleta)
        Else
            Dim listaFiltrata As List(Of RigaTabella) = _listaCompleta.
                FindAll(
                    Function(x)
                        Return x.C1?.ToLower.Contains(filtro.C1) And
                               x.C2?.ToLower.Contains(filtro.C2) And
                               x.C3?.ToLower.Contains(filtro.C3)
                    End Function
                )
            dgv.DataSource = ConvertiInDataTable(listaFiltrata)
        End If
    End Sub

    Private Sub btnPulisci_Click(sender As Object, e As EventArgs) Handles btnPulisci.Click
        tbxFiltro_C1.Text = ""
        tbxFiltro_C2.Text = ""
        tbxFiltro_C3.Text = ""
    End Sub

    Private Function ConvertiInDataTable(Of t)(ByVal list As IList(Of t)) As DataTable
        Dim table As New DataTable()
        If Not list.Any Then
            Return table
        End If

        Dim fields() = list.First.GetType.GetProperties
        For Each field In fields
            table.Columns.Add(field.Name, field.PropertyType)
        Next

        For Each item In list
            Dim row As DataRow = table.NewRow()
            For Each field In fields
                Dim p = item.GetType.GetProperty(field.Name)
                row(field.Name) = p.GetValue(item, Nothing)
            Next
            table.Rows.Add(row)
        Next

        Return table
    End Function
End Class

Public Class RigaTabella
    Public Property C1 As String
    Public Property C2 As String
    Public Property C3 As String
End Class

cover