none
Create Filter Cells in Data Grid View RRS feed

  • Question

  • hello

    I want to place "filter cell" at top of my DGV  and be compatible to DGV cell type. What shall I do and how can I create my own DGV with mentioned feature?

    thank you all

    Sunday, May 6, 2018 11:13 AM

All replies

  • Hello,

    Perhaps consider the following which can be implemented in several lines of code. I have a code sample to try it out. Your other option is to create your own component that would integrate into a standard DataGridView. 


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Sunday, May 6, 2018 11:26 AM
    Moderator
  • hello

    I want to place "filter cell" at top of my DGV  and be compatible to DGV cell type. What shall I do and how can I create my own DGV with mentioned feature?

    thank you all

    Hi

    Here is an alternative Filter example. This example filters 'as you type' and matches all of the shown types (dates, numeric and string).

    The example is a stand alone project.

    ' DataTable Filter RowFilter DGV DataGridView
    ' This code is an attempt to auto Filter DataTable
    ' rows on some of the most common Data Types
    ' String, Date, Boolean, Decimal, Integer where
    ' the columns can be in any order.
    
    ' This example needs a Form1 with
    ' a blank DataGridView1, 
    ' TextBox1 and Label1
    
    
    ' NOTE: to enable comparisons for the Filter,
    ' both Decimal and Double are compared as Decimal.
    
    Option Strict Off
    Option Explicit On
    Public Class Form1
        Dim myTable As New DataTable("Freddy")
        Dim rand As New Random
        Dim Path As String = Application.StartupPath & "\Data\Data.xml"
        Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
            Dim parent As String = My.Computer.FileSystem.GetParentPath(Path)
            If Not IO.Directory.Exists(parent) Then
                IO.Directory.CreateDirectory(parent)
            End If
            ' save data file when exit the application
            myTable.WriteXml(Path, XmlWriteMode.WriteSchema)
        End Sub
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            If IO.File.Exists(Path) Then
                ' data file found so load it
                myTable.ReadXml(Path)
            Else
                '  no Data file found so create dummy data
                With myTable
    		' add some random columns
    		.Columns.Add("Integer", GetType(Integer))
    		.Columns.Add("Boolean", GetType(Boolean))
    		.Columns.Add("Double", GetType(Integer))
    		.Columns.Add("First name", GetType(String))
    		.Columns.Add("Last name", GetType(String))
    		.Columns.Add("Gender", GetType(String))
    		.Columns.Add("DateTime", GetType(Date))
    		.Columns.Add("Decimal", GetType(Decimal))
    
    		' just some test data
    		Dim r1() As String = {"Freddy", "Mary", "Brian", "Led", "Smith", "Brown", "MacHine", "Elizabedh", "Jones", "Tom"}
                    Dim r2() As String = {"Male", "Female", "Undeclared"}
                    Dim r3() As Boolean = {True, False}
    
                    Dim md As Double = Double.MaxValue
    		.Rows.Add(3333, True, 1.99998, "Freddy", "MacHine", "Male", Now.AddDays(11).Date, 1.12)
    		.Rows.Add(3334, False, 123.12234567890127, "Mary", "Smith", "Female", Now.AddDays(12).Date, 1.25)
                    .Rows.Add(3335, True, 123.12234567890125, "Gedrge", "Mathews", "undeclared", Now.AddDays(13).Date, 1.255)
    
                    For i As Integer = 0 To 222
                        .Rows.Add(i, If(rand.Next(0, 2) = 1, "False", "True"), rand.NextDouble() * 10000, r1(rand.Next(r1.Length)), r1(rand.Next(r1.Length)), r2(rand.Next(r2.Length)), Now.Date, rand.NextDouble() * 100)
    
                    Next
                End With
            End If
    
            bs.DataSource = myTable
    
            ' just some formatting of DGV
            With DataGridView1
                .DataSource = bs
                .MultiSelect = False
                .RowHeadersWidth = 24
                .ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.False
                .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
                .SelectionMode = DataGridViewSelectionMode.CellSelect
                .Columns("Decimal").AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
                For Each c As DataGridViewColumn In .Columns
                    c.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
                Next
                .DefaultCellStyle.Padding = New Padding(8, 2, 2, 8)
                .Columns("DateTime").DefaultCellStyle.Format = "dd MMM yyyy"
                .AutoResizeRows()
            End With
            Label1.Text = "Rows = " & myTable.DefaultView.Count.ToString
        End Sub
      Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    	myTable.DefaultView.RowFilter = DoFilter(Trim(TextBox1.Text))
    	Label1.Text = "Rows = " & myTable.DefaultView.Count.ToString().ToString
      End Sub
    
      Function DoFilter(t As String) As String
    	If t.Length < 1 Then Return String.Empty
    	Dim fstring As String = Nothing
    	Try
    	  For Each c As DataColumn In myTable.Columns
    		Select Case c.DataType
    ' ======================
    ' Treat both Double and 
    ' Decimal as Decimal to
    ' enable matching
    ' ======================
    		  Case GetType(Decimal), GetType(Double)
    			Dim v As Decimal = 0
    			If Decimal.TryParse(t, v) Then
    			  fstring &= "[" & c.ColumnName & "] = '" & v & "' or "
    			End If
    
    		  Case GetType(Date)
    			Dim d As DateTime = Now
    			If Date.TryParse(t, d) Then
    			  fstring &= "[" & c.ColumnName & "] = '" & CDate(t) & "' or "
    			End If
    
    		  Case GetType(Boolean)
    			If t.ToLower = "true" Or t.ToLower = "false" Then
    			  fstring &= "[" & c.ColumnName & "] = '" & t & "' or "
    			End If
    
    		  Case GetType(Integer)
    			Dim v As Integer = 0
    			If Integer.TryParse(t, v) Then
    			  fstring &= "[" & c.ColumnName & "] = '" & v & "' or "
    			End If
    
    		  Case Else
    			fstring &= "[" & c.ColumnName & "] like '" & t & "' or "
    		End Select
    	  Next
    	  fstring = fstring.Substring(0, fstring.Length - 3)
          myTable.DefaultView.RowFilter = fstring
    
          ' to allow 'no matches' to show all
          '  If myTable.DefaultView.Count < 1 Then Return Nothing
    
        Catch ex As Exception
    	  MessageBox.Show("ERROR: " & ex.Message)
    	End Try
    	Return fstring
      End Function
    End Class
    
    


    Regards Les, Livingston, Scotland

    Sunday, May 6, 2018 12:03 PM
  • Hi mmbguide,

    About building a Drop-Down Filter List for a DataGridView Column Header Cell, Microsoft give one example, please take a look the following code:

    https://www.microsoft.com/en-us/download/details.aspx?id=23459

    Here is an article about this, you can take a look:

    https://msdn.microsoft.com/en-us/library/aa480727.aspx

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, May 7, 2018 7:52 AM
    Moderator