Click here to Skip to main content
15,896,557 members
Articles / Web Development / ASP.NET

A Filter Dialog for a DataGridView

Rate me:
Please Sign up or sign in to vote.
4.04/5 (9 votes)
28 Sep 20067 min read 114.1K   4.5K   75  
This is a dialog window that allows filtering a DataGridView. It can build filters with any depth of parentheses.
'' FILENAME:        Filter.vb
'' NAMESPACE:       PI.Dialogs.Filter
'' APPLICATION:     N/A
'' CREATED BY:      Luke Berg
'' CREATED:         8-15-06
'' REVISED BY:      Luke Berg   
'' REVISED:         8-30-06
'' DESCRIPTION:     The filter dialog window.

Imports System.Windows.Forms

''' <summary>
'''  A filter dialog to be tied to a datagrid view, and return a filter string
''' </summary>
''' <remarks>
'''  As of now, this will only allow filtering of gridviews whose datasource is ultimately
'''  tied to a datatable.
''' </remarks>
Public Class Filter

    Private _Fields As List(Of FilterItemField) '' the list of fields of the datasource
    Private _DistinctDisplayLevel As System.Single = 0.1 '' The amount of distinct items below which to use a dropdown expression
    Private _UseDistinctDisplayLevel As Boolean = True '' Whether to automatically build lists of the distinct items
    Private _DataGrid As DataGridView

#Region "Properties"

    ''' <summary>
    '''  The list of fields of the datasource
    ''' </summary>
    Private Property Fields() As List(Of FilterItemField)
        Get
            Return _Fields
        End Get
        Set(ByVal value As List(Of FilterItemField))
            _Fields = value
        End Set
    End Property

    ''' <summary>
    '''   If this property is set between 0 and 1, and UseDistinctDisplayLevel is set to true, the generateFields
    '''   function will add a combobox to any field (column) whose percent of distinct / total items is less than
    '''   the DistinctDisplayLevel.
    '''   If this property is set above 1 and UseDistinceDisplayLevel is set to true, the generateFields function will
    '''   add a combobox to any field (column) whose number of distinct items is less than the DistinctDisplayLevel.
    ''' </summary>
    ''' <value>A percentage between 0 and 1 or an integer (any decimal value will be truncated) greater than 1</value>
    ''' <returns>The percentage</returns>
    ''' <remarks></remarks>
    Private Property DistinctDisplayLevel() As System.Single
        Get
            Return _DistinctDisplayLevel
        End Get
        Set(ByVal value As System.Single)
            If value >= 0 Then
                _DistinctDisplayLevel = value
                Me.Fields = GenerateList(DataGrid)
            End If
        End Set
    End Property

    ''' <summary>
    '''   Whether to display some generated fields as combobox options determined by using the 
    '''   distinctDisplayLevel
    ''' </summary>
    Private Property UseDistinctDisplayLevel() As Boolean
        Get
            Return _UseDistinctDisplayLevel
        End Get
        Set(ByVal value As Boolean)
            _UseDistinctDisplayLevel = value
            Me.Fields = GenerateList(DataGrid)
        End Set
    End Property

    ''' <summary>
    '''   The Filter that this dialog box represents
    ''' </summary>
    ''' <value></value>
    Public ReadOnly Property Filter() As String
        Get
            Return FilterItemGroup1.Filter
        End Get
    End Property

    ''' <summary>
    '''   The DataGridView that this filter dialog points to
    ''' </summary>
    Private Property DataGrid() As DataGridView
        Get
            Return _DataGrid
        End Get
        Set(ByVal value As DataGridView)
            _DataGrid = value
        End Set
    End Property

#End Region

#Region "Constructors"

    ''' <summary>
    '''   The generic constructor for use by the designer
    ''' </summary>
    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        FilterItemGroup1.Fields = Fields
        FilterItemGroup1.AddFilterItem(New FilterItem(FilterItem.FieldTypes.StringExpression, Fields))
    End Sub

    ''' <summary>
    '''   Another contructor that allows you to build your own custom list of fields
    ''' </summary>
    ''' <param name="fields">Sets the fields if the user desires to manually build the fields list</param>
    Public Sub New(ByVal fields As List(Of FilterItemField))

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.Fields = fields
        FilterItemGroup1.Fields = fields
        FilterItemGroup1.AddFilterItem(New FilterItem(FilterItem.FieldTypes.StringExpression, fields))
    End Sub

    ''' <summary>
    '''  Constructor that builds the list of fields from a datagrid view tied to a datatable
    ''' </summary>
    ''' <param name="dataGridView">The dataGridView from which to get the fields</param>
    ''' <param name="distinctDisplayLevel">
    '''  Sets the <see cref="DistinctDisplayLevel">Distinct Display Level</see>  
    ''' </param>
    ''' <param name="useDistinctDisplaylevel">Sets the <see cref="UseDistinctDisplayLevel">UseDistinctDisplayLevel</see> property</param>
    Public Sub New(ByVal dataGridView As DataGridView, ByVal distinctDisplayLevel As Single, ByVal useDistinctDisplaylevel As Boolean)

        ' This call is required by the windows form designer
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.DataGrid = dataGridView
        Me._DistinctDisplayLevel = distinctDisplayLevel
        Me._UseDistinctDisplayLevel = useDistinctDisplaylevel
        Me.Fields = GenerateList(dataGridView)
        FilterItemGroup1.Fields = Fields
        FilterItemGroup1.AddFilterItem(New FilterItem(FilterItem.FieldTypes.StringExpression, Fields))
    End Sub

#End Region

#Region "Public Functions"

    ''' <summary>
    '''   Generates a list of fields from a datagridview
    ''' </summary>
    ''' <param name="gridView">The dataGridView from which to generate the fields</param>
    ''' <returns>A list of fields</returns>
    Public Function GenerateList(ByVal gridView As DataGridView) As List(Of FilterItemField)
        Dim fields As New List(Of FilterItemField)
        Dim table As DataTable = SharedDataFunctions.GetSourceTable(Me._DataGrid)

        If Not table Is Nothing Then
            '' Loop through all the columns in the dataview, and adds a field to the list
            For Each column As DataGridViewColumn In gridView.Columns
                fields.Add(GenerateField(column.HeaderText, table.Columns(column.DataPropertyName), table))
            Next
        End If

        Return fields
    End Function

    ''' <summary>
    '''  Clears the filterItems for the dialog
    ''' </summary>
    Public Sub ClearFilterItems()
        FilterItemGroup1.ClearFilterItems()
    End Sub

#End Region

#Region "Handlers"

    ''' <summary>
    '''   Handles the ok button click
    ''' </summary>
    ''' <param name="sender">the sender of the event</param>
    ''' <param name="e">the arguments of the event</param>
    Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.OK
        Me.Close()
    End Sub

    ''' <summary>
    '''   Handles the cancel button click
    ''' </summary>
    ''' <param name="sender">the sender of the event</param>
    ''' <param name="e">the arguments of the event</param>
    Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
        Me.Close()
    End Sub

    ''' <summary>
    '''   Handles the clear button click
    ''' </summary>
    ''' <param name="sender">the sender of the event</param>
    ''' <param name="e">the arguments of the event</param>
    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        FilterItemGroup1.ClearFilterItems()
    End Sub

#End Region

#Region "Private Functions"

    ''' <summary>
    '''   Generates a filter item from a given column
    ''' </summary>
    ''' <param name="display">The text to display for the column in the dropdownlist of fields</param>
    ''' <param name="column">The column for which to create a field</param>
    ''' <param name="table">The table in which the column is found</param>
    ''' <returns>A filterItemField</returns>
    Private Function GenerateField(ByVal display As String, ByVal column As DataColumn, ByVal table As DataTable) As FilterItemField
        Dim distinctValues As List(Of String)
        Dim columnType As Type = column.DataType

        '' If the generator should allow for combo box filter expressions, calculate the distinct values
        If UseDistinctDisplayLevel Then
            distinctValues = CountDistinct(table, column.ColumnName)
        End If

        If column.DataType.Equals(GetType(System.DateTime)) Then

            '' Add a date expression filter item
            Return New FilterItemField(column.ColumnName, display, FilterItem.FieldTypes.DateExpression)

        ElseIf UseDistinctDisplayLevel AndAlso DistinctDisplayLevel <= 1 AndAlso _
          (distinctValues.Count / table.Rows.Count) <= DistinctDisplayLevel Then

            '' Adds a combobox expression filter item using the distinct values list of values
            Return New FilterItemField(column.ColumnName, display, FilterItem.FieldTypes.DropDownExpression, distinctValues)

        ElseIf UseDistinctDisplayLevel AndAlso DistinctDisplayLevel > 1 AndAlso _
          (distinctValues.Count <= DistinctDisplayLevel) Then

            '' Adds a combobox expression fitler item using the distinct values list of values
            Return New FilterItemField(column.ColumnName, display, FilterItem.FieldTypes.DropDownExpression, distinctValues)

        ElseIf columnType.Equals(GetType(System.Int32)) Or columnType.Equals(GetType(System.Single)) _
          Or columnType.Equals(GetType(System.Double)) Or columnType.Equals(GetType(System.Decimal)) Then

            '' Add a number expression filter item
            Return New FilterItemField(column.ColumnName, display, FilterItem.FieldTypes.NumberExpression)

        Else

            '' Add a string expression filter item
            Return New FilterItemField(column.ColumnName, display, FilterItem.FieldTypes.StringExpression)
        End If

    End Function

    

#End Region

End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions