Using AutoCompleteBox

Jun 30, 2010 at 2:47 AM

I am trying to use the AutoCompleteBox to implement a filesystem based auto-completion, ala the run prompt (though only for folders).
The AutoCompleteBox seems to work well if you have a static list, but I am trying to update the list with every keystroke.  I am still having problems, and I'd like some help.  Here's the problems I've had so far, and what I've done to solve some of them:

The first problem I had was that the Text property is not pushed down to the DataContext every time the text changes.  This is true of a TextBox, as well, so I expected this.  To get around the problem, I added a TextChanged handler (so I could handle deleting text, otherwise I'd use a TextInput handler).  Every time the handler is called, I update the DataContext's "Folder" property (which is bound to AutoTextBox.Text), and the completion list.


This caused a second problem.  Every time the selection changes, the text changes, which updates the completion list.  This broke browsing the completion list, because every time you selected an item (without commiting the selection), it would update the list, and kick the user out of the dropdown.  For example, you couldn't pick an item in them middle by using the keyboard.
I tried many different combinations of hacks to solve the second problem, including handling various events, checking the SearchText, Text and SelectedItem properties, and trying to store and compare old values of properties between combinations of events.  What I settled on to solve this was to check if the selected item's text was not equal to the text field (or if it was null).  This solved the second problem.


The third problem I have now is when the user selects an item from the list, if they start typing again, their selection is undone.
Try this:  At the Run prompt: Type "C:\", select an item via the keyboard, then hit the "\" key.  It will continue typing and update the auto-completion based on that.
In the app I have now: The user types "C:\", selects an item via the keyboard, then hits the "\" key.  The app ignores the newly typed "\", kicks the user out of the popup, and reverts the text to whatever was typed before the popup was displayed.

Here is the code I have so far (note: I've stripped out a little code.  That code is working correctly, though, including the code that sets dataContext):

public MyView()
    folderChooserBox.TextChanged += folderChooserBox_TextChanged;

void folderChooserBox_TextChanged(object sender, RoutedEventArgs e)
    var newText = folderChooserBox.Text;
    var selectedItem = folderChooserBox.SelectedItem;

    if (selectedItem == null || (string)selectedItem != newText)
        dataContext.Folder = newText;