Class to Add Instant ‘As You Type’ Filter Functionality to Infragistics UltraCombo Control

In my last blog post, I talked about a filter enhancement to a ComboBox that could be added to a single combo box with just one line of code. The blog post wasn’t necessarily to talk about the code, but was to talk about a good architecture and the importance of a good architecture for a system or application.

The filter component follows a sound architectural strategy as it is something that we could write once and easily reuse many times. Please see the blog post about the architecture here: Getting to the Monetary Value of Software Architecture

This post will focus on the actual class that was created in order to allow us to have this functionality.
The code was designed for WinForms Infragistics UltraCombo controls (v6.2 CLR2.0). These controls are multi column drop down lists, essentially. We’re using this control and not the native WinForms ComboBox because of the multi column ability. In this organization, we use a lot of Infragistics controls, but there are other vendors who make very good controls as well.

Before (without filter functionality):
image

After (with new filter functionality enabled):
image

(Some information in screen shots above is blurred out to protect customer confidentiality)

As the user is typing into the UltraCombo control the list filters based on what they are typing. In the example above the user has typed in ‘007’, so the list shows any items that have ‘007’ somewhere in the value. As the user is typing in order to filter, a filter icon is displayed in the UltraCombo. All of this functionality is encapsulated in the UltraComboTypeFilter class.

Here is the code for the UltraComboTypeFilter class that will give any UltraCombo control this functionality:

''' <summary>
''' Class is used to encapsulate functionality to allow user to type into 
''' ultra combo drop down and have the list display and filter the list as 
''' the user types 
''' Dan Douglas Mar 5, 2010 https://dandouglas.wordpress.com
''' </summary>
''' <remarks></remarks>
Public Class UltraComboTypeFilter
    Dim UltraComboControl As Infragistics.Win.UltraWinGrid.UltraCombo
    Dim KeyColumn As String
    Dim _FilterImage As Image

    ''' <summary>
    ''' Create a new instance of the UltraComboTypeFilter class
    ''' </summary>
    ''' <param name="UltraCombo">The Infragistics UltraComboBox control to apply the filter functionality to</param>
    ''' <param name="ColumnToFilter">The key of the column you want to be searched for filtering</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal UltraCombo As Infragistics.Win.UltraWinGrid.UltraCombo, ByVal ColumnToFilter As String)
  
UltraComboControl = UltraCombo

        'Add handlers so that the methods in this class can handle the events from the control
        AddHandler UltraComboControl.KeyUp, AddressOf ucbo_KeyUp
        AddHandler UltraComboControl.AfterCloseUp, AddressOf ucbo_AfterCloseUp
        AddHandler UltraComboControl.TextChanged, AddressOf ucbo_TextChanged
        AddHandler UltraComboControl.BeforeDropDown, AddressOf ucbo_BeforeDropDown

        KeyColumn = ColumnToFilter

        FilterImage = My.Resources.FilterIcon() 'the filter icon is storred as an embedded resource in the resource file

        'turn off automatic value completion as it can potentially interfere at times with the search/filter functionality
        UltraComboControl.AutoEdit = False

        HideFilterIcon()
        UltraComboControl.Appearance.ImageHAlign = Infragistics.Win.HAlign.Right 'filter icon will be always displayed on the right side of the text area of the control

        ClearCustomPartFilter() 'by default, clear filters
    End Sub

    Private Sub ShowFilterIcon()
        'add the filter icon to the ComboBox
        UltraComboControl.Appearance.Image = FilterImage
    End Sub

    Private Sub HideFilterIcon()
        UltraComboControl.Appearance.Image = Nothing
    End Sub

    Private Sub ucbo_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        If Trim(UltraComboControl.Text) = "" Then
            ClearCustomPartFilter() 'if there are no characters in the textbox (from dropdown) then remove filters
        End If
    End Sub

    Private Sub ClearCustomPartFilter()
        'clear any filters if they exist 
        UltraComboControl.DisplayLayout.Bands(0).ColumnFilters.ClearAllFilters()
        HideFilterIcon()
    End Sub

    Private Sub DoPartDropDownFilter()
        UltraComboControl.DisplayLayout.Bands(0).ColumnFilters.ClearAllFilters()
        UltraComboControl.DisplayLayout.Bands(0).ColumnFilters(KeyColumn).FilterConditions.Add(Infragistics.Win.UltraWinGrid.FilterComparisionOperator.Like, "*" & UltraComboControl.Text & "*")
        ShowFilterIcon()
    End Sub

    Private Sub ucbo_BeforeDropDown(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)
        'clear any filters if they exist before the user drops down the list, if the user starts typing again - filter will be shown
        'this is done so that if the user leaves the combo box and then goes back to it and drops down the list the full list will be 
        'there until they start typing a filter again; this is by design
        ClearCustomPartFilter()
    End Sub

    Private Sub ucbo_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
        'the code in this method is to start the filtering process to filter the drop down list if the drop down isn't 'dropped'
        'with thi procedure the user can just start typing into the combo box and have the box drop down automatically and filter
        'KeyPress event is not used because of timing issues - the timing of the event is too late for us to filter properly

        'Do not do filter or drop down if user hits ESC - also we will check other non entry keys like Left, Right, etc)
        ''Array of keys that we won't do anything with

        Dim IgnoreKeys As New List(Of Integer)
        IgnoreKeys.Add(Keys.Left)
        IgnoreKeys.Add(Keys.Right)
        IgnoreKeys.Add(Keys.Up)
        IgnoreKeys.Add(Keys.Down)
        IgnoreKeys.Add(Keys.Escape)
        IgnoreKeys.Add(Keys.Enter)

        If IgnoreKeys.Contains(e.KeyCode) = False Then
            'if inputted key press is valid for drop down filtering
            Dim iSelLoc As Integer = UltraComboControl.Textbox.SelectionStart 'get location of cursor
            If UltraComboControl.IsDroppedDown = False Then
                UltraComboControl.ToggleDropdown()
                'toggling drop down causes all text to be highlighted so we will deselect it and put the cursor position back where it was instead of being at 0
                UltraComboControl.Textbox.SelectionLength = 0
                UltraComboControl.Textbox.SelectionStart = iSelLoc
            End If

            DoPartDropDownFilter()
        End If

    End Sub

    ''' <summary>
    ''' The image to use for the filter icon shown on the control to be displayed while the control is filtered
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property FilterImage() As Image
        Get
            Return _FilterImage
        End Get
        Set(ByVal value As Image)
            _FilterImage = value
        End Set
    End Property

    Private Sub ucbo_AfterCloseUp(ByVal sender As Object, ByVal e As System.EventArgs)
        ClearCustomPartFilter()
    End Sub

    Protected Overrides Sub Finalize()
        RemoveHandler UltraComboControl.KeyUp, AddressOf ucbo_KeyUp
        RemoveHandler UltraComboControl.AfterCloseUp, AddressOf ucbo_AfterCloseUp
        RemoveHandler UltraComboControl.TextChanged, AddressOf ucbo_TextChanged
        RemoveHandler UltraComboControl.BeforeDropDown, AddressOf ucbo_BeforeDropDown
        MyBase.Finalize()
    End Sub
End Class

Now, to enable the functionality on any UltraCombo control just use one single line of code.

Dim PartFilterFunction As New UltraComboTypeFilter(ucboPart, "CustPartNo")

Add the filter icon/image as a resource to the project that contains the UltraComboTypeFilter class and name the resource FilterIcon.

Advertisements

About dandouglas
Dan Douglas is based in Toronto, Ontario, Canada and is a professional independent Software Consultant and an experienced and proven subject matter expert, decision maker, and leader in the area of Software Development and Architecture. His professional experience represents over 15 years of architecting and developing highly successful large scale solutions. Dan also believes that properly empowering teams with trust and responsibility yields the greatest results. | For inquiries about Dan's software consulting practice, please see the contact page.  Dan has also built up a network of highly successful and professional Software Developers and Architects who are highly respected and can be called upon and used in conjunction with his own consulting practice to handle the largest of consulting projects.

7 Responses to Class to Add Instant ‘As You Type’ Filter Functionality to Infragistics UltraCombo Control

  1. Pingback: Measuring the Time Saved When Reusing a Well Architected Component « IT is Possible – Dan Douglas is blogging

  2. german hernandez says:

    hola amigo me podrias mandar un ejmplo de este codigo multicolumnas combobox…eske no le entendi-.-.
    ya que stoy aciendo una aplicacion en donde muestre por medio de combobox varias columnas..

  3. Hussain Shifau says:

    Hi,
    Thank you for the great post. I have tested the control with this functionality. Just one problem. If the user filters list does not show anything user cannot exit the control. Whats the solution to this problem.
    Thorn_head

  4. dandouglas says:

    Hi Hussain, that’s a good question, however we never experienced this problem in our own implementations. I hope that you were able to find a solution to this.

  5. Simon K says:

    Thanks for the sample. It was really useful!

  6. David Andrews says:

    Thanks for the post. I was trying to create similar functionality for an ultradropdown. Is it possible to do it this way as the ultradropdown does not have a property for textbox.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s