(Print this page)

A more useful auto-complete Textbox control
Published date: Monday, April 16, 2012
On: Moer and Éric Moreau's web site

I have already written about the AutoComplete feature of the Textbox control in 2006 (see http://www.emoreau.com/Entries/Articles/2006/06/The-TextBox-and-the-MaskedTextbox-controls.aspx). This feature works well when you type the first few letters of a word. The list will then be filtered to show only the values starting with these letters.

But what if your users would like a Contains instead of a StartsWith? Will you tell them you can’t do anything for them? The out-of-the-box control doesn’t support it but that doesn’t mean you cannot do anything yourself!

Another useful feature supported by this extension is that multiple values can be inputted into the same Textbox and still be able to get the suggestions list shown.

The demo solution

The solution this month contains code both in VB and C# and was saved with Visual Studio 2010. You would be able to do exactly the same thing with any version of .Net. This particular example uses generics and other recent approaches that could easily be transformed to older version of .Net.

The complete code is not copied into this article. I strongly encourage you to download the demo solution that is available with this article.

Create the base of the test form

We will start by creating the base of the test form.

Figure 1: Building the test form

As shown in figure 1, the test form is composed of 3 regular controls:

  • A Textbox control with no modified properties
  • A Button control with a Caption set to Show and the Name set to btnShow
  • A ListBox control with a Name set to lstSelectedValues

 

When the form is loaded, the first thing it does is to initialize the ListBox that will be used to display the suggestion (not the one we just added to the UI). This initialization is all in the InitializeAutoComplete method which is called from the constructor of the form:

Private Sub InitializeAutoComplete()
    Me.SuspendLayout()
    'Create a new listbox that will be shown for the auto-complete
    ' 
    ' _listBox
    ' 	
    _listBox = New System.Windows.Forms.ListBox()
    _listBox.Visible = False
    _listBox.Location = New System.Drawing.Point(0, 0)
    _listBox.Name = "_listBox"
    _listBox.Size = New System.Drawing.Size(120, 96)
    _listBox.TabIndex = 0
    AddHandler _listBox.MouseDown, AddressOf _listBox_MouseDown

    Me.ResumeLayout(False)
End Sub

All this code does is to instantiate a ListBox and keep it invisible until later use.

Displaying filtered values

The original list of values is provided in an array at the top of the form:

Private _values As String() = {"Chopin, Frederic",
                               "Dalton, Averell",
                               "Dalton, Jack",
                               "Dalton, Joe",
                               "Dalton, William",
                               "Moreau, Eric"}

Whenever a key is pressed in the textbox, we need to check that list of values to filter for the values matching what is currently typed and display them in the ListBox but not only with the StartsWith but really with a case-insensitive Contains. This method is called UpdateListBox and is called from the KeyUp event of the Textbox.

If you are using a recent version of Visual Studio, you can use the FindAll method of the Array component. This method takes a lambda expression for the match expression which can be expressed like this:

Dim matches As String() = Array.FindAll(_values,
                                        Function(x) (x.ToUpper().Contains(word.ToUpper()) AndAlso
                                                     Not SelectedValues.Contains(x)))

If this method returns values (in the matches variable), they will be shown in the ListBox and the the ListBox will be shown. If there is no more matches (because you made a typo for example), the ListBox is hidden.

Figure 2: The auto-complete in action

Other events

Another event you need to handle is the KeyDown of the Textbox control to catch the Up and Down arrow keys to change the SelectedItem in the ListBox.

You will also want to handle the PreviewKeyDown to catch the tab key. What you want to do when the tab key is pressed and the ListBox is opened is to select the active item of the Listbox and add the value to Textbox.

Conclusion

The experience provided by this extension of the Auto-Complete feature will be much appreciated by your users.

You will surely want to encapsulate this code into a new control to ease reuse. I haven’t done it here because you probably have your own extended textbox to which you will want to add this new feature.


(Print this page)