WPF Auto Complete Text Box

A simple and useful control for WPF. It supports Binding and MVVM. 

Features:
  • Supports MVVM for auto suggestions
  • Asynchronously load suggestions
  • Supports watermark
  • Supports Icon

Latest release of AutoCompleteTextBox is available at CodePlex or Visual Studio Gallery.

WPF Auto Complete Text Box

Below is a sample code of FilesystemSuggestionProvider.

Public Class FilesystemSuggestionProvider
    Implements ISuggestionProvider

    Public Function GetSuggestions(ByVal filter As String) As System.Collections.IEnumerable Implements ISuggestionProvider.GetSuggestions
        If String.IsNullOrEmpty(filter) Then
            Return Nothing
        End If
        If filter.Length < 3 Then
            Return Nothing
        End If

        If filter(1) <> ":"c Then
            Return Nothing
        End If

        Dim lst As New List(Of IO.FileSystemInfo)
        Dim dirFilter As String = "*"
        Dim dirPath As String = filter
        If Not filter.EndsWith("\") Then
            Dim index As Integer = filter.LastIndexOf("\")
            dirPath = filter.Substring(0, index + 1)
            dirFilter = filter.Substring(index + 1) + "*"
        End If
        Dim dirInfo As IO.DirectoryInfo = New IO.DirectoryInfo(dirPath)
        lst.AddRange(dirInfo.GetFileSystemInfos(dirFilter))
        Return lst
    End Function

End Class

Adding AutoCompleteTextBox in your view:

<wpf:AutoCompleteTextBox VerticalAlignment="Top"
     Height="25"
     Grid.Column="1"
     Text="{Binding Path=FileName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
     DisplayMember="FullName"
     ItemTemplate="{StaticResource ResourceKey=fsTemplate}"
     Provider="{StaticResource ResourceKey=fsp}" /> 

17 comments

Thank you very much for the control. I just had an issue with MVVM and the selected item from the suggestion area, had to solve it in code behind.

Anyway, good work!

Hi,
How did you solve selected item with a left clic on the suggestion area ? In MVVM, the binding value is changed before.

Thanks for your help

I have the same problem. Can you assist?

Hi :)
Thank you very much for this control :) I noticed suggested items were not clickable in my application so I tweaked your code and published the fix on github (https://github.com/CaptaiNapalm/WPF-AutoComplete). Anyway it worked really well, good job :>

Thanks Markus for sharing the issue. I have fixed the issue in my repository. Additionally I have added the mouse hover style for suggestions. You may download the updated source code from CodePlex.

Thanks again!! :)

Thanks ShaBang for appreciations. I have also fixed the issue in CodePlex repository and additionally I have added mouse hover style for suggestions.

Hello, thank you for the control.

I'm newer to WPF and can't figure out how to fire an event when the user selects a item in the drop down. Can you please advise how to do this? It has been a good learning experience so far to get this working with my application!

Hi Clint,

If you are using MVVM design pattern then you just need to bind the SelectedItem property of the control with a property in your model or view-model.

I got this warning when I tried compiling your solution on Visual Studio 2015:
Could not find rule set file "MinimumRecommendedRules.ruleset"

Hey Deepak,

I am currently using your control for auto suggest. Thank you so much for the control. It is really good.

However, I am facing one issue wherein when i replace your example (directory info) with my own objects, there is some issue with selected items.

Here is the issue
When i start typing in the search box, i see the suggestions. When I hit the down arrow key and select items from the suggestions, they don't populate the search box.

I tried debugging and i found that the Evaluate method in BindingEvaluator is not getting the value out of the object dataItem. Some issue with SetBinding? Could you provide some pointers or solution to this issue. I would be really grateful.

Thank you once again
Pranav

Hi Pranav,

Did you change DisplayMemberPath? As you said you are using your own class's objects in suggestion, you would want to change the display member path (Name of property you want to display for selected object)

HI!

I'm having such an issue: I have an object. One of its fields can be selected from your autocomplete. The problem is that when I open a new window for editing my object autocomplete is not populated immidiately with the value of the property it is bound to.

Instead it populates texteditor's text (but does not set SelectedItem) and suggests to select an item from the drop-down list which contains this one item.

How can I make binding work correctly so that autocomplete is bound immidiately without having to select already selected item.

OK, it looks like the problem is that I'm openning a window with a static method in this window. I had such code:

public static bool? ShowField402(Field402 item, IEnumerable services, IEnumerable countries)
{
var window = new COIFields402EditorWindow();
window.Owner = Application.Current.MainWindow;
window.Item = item;
window.DataContext = window.Item;
window.Services = services;
window.Countries = countries;
return window.ShowDialog();
}

It looks like setting DataContext is the root of my problem. In this case OnSelectedItemChanged fires before OnApplyTemplate. My workaround is setting DataContext in Window_Loaded event:

this.DataContext = this.Item;

Can you comment this solution?

Also:

1) It would be nice to have an ability to reset selected item. Either by a separate button on the right, or autoselect all text when Editor gets focus. It is very inconvinient to select all text manually and delete it.
2) I added F4 to show drop-down, it's rather standard behaviour:

private void OnEditorKeyDown(object sender, KeyEventArgs e)
{
if (SelectionAdapter != null)
{
if (IsDropDownOpen)
SelectionAdapter.HandleKeyDown(e);
else
IsDropDownOpen = e.Key == Key.Down || e.Key == Key.Up || e.Key == Key.F4;
}
}

I had the same issue trying to use the autocomplete to add items to a list as they were selected. This use case makes binding less than ideal =). I used the code below. It binds to the Commit event (when an item is actually selected) upon loading the control, then when Commit is fired it adds the selected item from the control to my list and clears out the control for "fresh" use.

private void DXAutoCompleteTextBox_Loaded(object sender, RoutedEventArgs e)
{
AutoCompleteTextBox ACT = (AutoCompleteTextBox)e.Source;
ACT.SelectionAdapter.Commit += DXSelectionAdapter_Commit;
}

private void DXSelectionAdapter_Commit()
{
dxView.Add((DX)actDX.SelectedItem);
dgDX.Items.Refresh();
actDX.SelectedItem = null;
actDX.Text = "";
}


Emoticon Emoticon