Ioannis Panagopoulos blog

Tutorials on HTML5, Javascript, WinRT and .NET

Autosuggest Textbox for WPF

by Ioannis Panagopoulos

Here is an implementation of a nice Textbox in WPF that suggests possible values based on the current user’s input. It is different from WPF’s native editable Combobox since it does not load all possible values at initialization (saving time and memory). The Textbox calls a method that returns the suggested values as soon as it detects a specific amount of idle time in the user’s typing. This method will probably access the database using the value entered so far in the Textbox as the criterion for the suggested values.

The main idea is as follows:

We create a grid whose first row contains a textbox and the second row contains a Listbox. Now, when the textbox gets the focus and its text changes due to the user’s input, between the user’s key presses we start a countdown timer. If the timer reaches zero before the user pressing another button, we call a method to retrieve the suggested values and display the textbox with those values. Now, if the user selects one of them, then we fill the textbox with the appropriate selection.

The TTimer.cs file contains the TTimer class that creates a primitive countdown timer:

public class TTimer
    {
        private Timer timer;
        public event Action<int> DoSomething;
        private int _timesCalled = 0;
 
        public TTimer()
        { }
        public void Start(int PeriodInSeconds)
        {
            timer = new System.Threading.Timer(timer_Task, null, 0,
            PeriodInSeconds * 1000);
        }
        public void Stop()
        {
            if (timer!=null)
            timer.Dispose();
        }
        private void timer_Task(object State)
        {
            _timesCalled++;
            DoSomething(_timesCalled);
        }
    }

The Autosuggest Textbox is implemented in AutoSuggestTextBox.xaml(.cs) and it is called TextBoxAS. Its properties are:

IdleTime: Defines the time to wait for the ListBox to appear when the user is idle.

ListHeight: Is the height of the Listbox with the suggested values.

ValueMember: Is the property of the objects in the list that should appear in the Textbox if the object is selected (.ToString() is used if empty).

DisplayMember: The property of the objects in the list that is displayed in the list (.ToString() is used if empty).

SelectedValue: Is the selected value from the ListBox.

The rest of the implementation is catching events and responding accordingly. The main action behind the events are summarized in the following list:

 

  • TextBox – TextChanged: When the text of the Textbox is changed if the Listbox is visible (_suggestingIsActive is true) we hide it since a new cycle should begin otherwise (_suggestingIsActive=false) we reset the countdown.
  • ListBox – SelectionChnaged: When the user has selected something from the ListBox we set this value to the SelectedValue dependency property.
  • TextBox-LostKeyboradFocus: When the TextBox loses the focus it is either because the user clicked on a value in the ListBox or because the user has navigated away to another control. If the first is true then if the SelectedValue DP has something, we use it to set the value of the TextBox. If the second is true we try to see whether the value entered in the TextBox can help us set the SelectedValue (there is only one suggestion for the value). Otherwise we revert to the previous value.
  • TextBox-GotKeyboradFocus: Initializes the timer.

 

The TextBox defines the event OnGetSuggestions that can be used to set the method to be called when the control needs to get the suggestions for a specific text.

Typical usage of the control is as follows:

<Controls:TextBoxAS Name="ASTextBox" 
                    Width="233" Height="171" Canvas.Left="28" Canvas.Top="25"  
                    OnGetSuggestions="TextBoxAS_OnGetSuggestions" 
                    DisplayMember="FullDescription" ValueMember="Name" 
                    ListHeight="150" />

In order to allow the ListBox to open on top of other controls, those controls should be defined in xaml before the definition of the TextBox.

You can download the sources for the project here

Shout it

blog comments powered by Disqus
hire me