views:

307

answers:

2

I'm trying to implement behaviour similar to the Firefox 3 AwesomeBar in WPF. I've got a ComboBox to use a DataTemplate that makes the dropdown look like the dropdown for the AwesomeBar, but I'm not sure how to get the right behaviour.

What I want to happen is for the user to type their search into the TextBox bit of the ComboBox and then to gradually narrow down the results in the dropdown. I think I can probably get the database querying part of that working (as the results will be coming from the database) but what I want to get is the dropdown bit to open up as soon as the user starts typing (as it does in firefox 3) and then the first item in the list to be automatically selected and other items in the list to be able to be selected by use of the arrow keys or by clicking on them.

Update:

I've now found the programmatic way to get the ComboBox to drop down (using IsDropDownOpen = true) but I still have a few other problems:

Firstly when I type something, it drops down but it doesn't select the match closest to what I'm typing, and secondly when I type something which uniquely selects an item it automatically closes and runs the SelectedItemChanged method. I want it to only close and run the code when I've actually clicked on it or pressed enter (rather than just had the selection on it by using the up or down arrows). Any ideas how to get it to do what I want? I can give more information if that's not clear enough.

+3  A: 

Most of the functionality you want is already in the ComboBox.

Is there a programmatic way to tell the ComboBox list to drop down?

Yes, you can do this by setting the ComboBox.IsDropDownOpen property to true.

And is there a way for an item to be selected without it closing the list and becoming the selected item?

When you set IsEditable to true, it will select the first item that matches the inputted text for you - when you drop down the item will still be selected. This example doesn't perform the filtering from a larger data set, but it should get you started:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:sys="clr-namespace:System;assembly=mscorlib"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <Grid.Resources>
        <x:Array x:Key="data" Type="{x:Type sys:String}">
            <sys:String>Veni</sys:String>
            <sys:String>Vidi</sys:String>
            <sys:String>Vici</sys:String>
        </x:Array>
    </Grid.Resources>
    <ComboBox x:Name="myCombo" ItemsSource="{StaticResource data}" IsEditable="True" PreviewTextInput="myCombo_PreviewTextInput"/>
</Grid>

In code behind we open the ComboBox. Your handler might do the filtering here as well:

private void myCombo_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    myCombo.IsDropDownOpen = true;
}
Robert Macnee
Thanks.I've tried that, but it doesn't seem to dropdown when I type something which is unique enough to select an item directly. Also, this only works for selecting items that start with the characters you are typing - I'd want to make it search in the whole string. Any ideas how to change this?
robintw
A: 

Use a CollectionView to access your collection.

ListCollectionView _myCollectionView = new ListCollectionView(someCollection);

Bind your ComboBox to this CollectionView. What this will provide is a Filter mechanism. Implement a filtering method(SearchText in this code would be your ComboBox text...I would store this in a DP called SearchText and update it from the ComboBox):

private bool FilterMethod(string expression)
{

     if (expression != null && this.SearchText != null)
     {
          if (expression.ToUpper().Contains(this.SearchText.ToUpper()))
              return true;

          else
              return false;
     }

     return true;
}

Now, when the user types something, use this filtering method on the CollectionView:

_myCollectionView.Filter = new Predicate<string>(FilterMethod);
Brent Schooley