Silverlight 5 Tidbits–Data binding Silverlight 5 Tidbits–Trusted applications

Silverlight 5 Tidbits–Incremental Search

Published on Monday, April 25, 2011 12:30:00 PM UTC in Programming

Edit 2011-12-11: This article is compatible with the final version of Silverlight 5 (5.0.61118.0).

This post is part of a mini series about Silverlight 5:

Incremental search (sometimes referred to as "type-ahead search") for items controls is one of the features that business users simply expect as a given. If they have a list of items, they want to be able to select one by simply typing the first few letters on the keyboard. Unfortunately, this feature has been missing in Silverlight until now. To this day, I sometimes was still reusing code I have written for this in the days of Silverlight 2. In this post we'll see how this changes with Silverlight 5.

What's new in Silverlight 5

In Silverlight 5, this feature is enabled by default for controls like the list box and combo box. Here is some sample code:

<StackPanel Width="250">
    <ListBox ItemsSource="{Binding Items}" />
    <ComboBox ItemsSource="{Binding Items}" />
</StackPanel>

For testing, I'm simply adding some sample data:

Items = new List<string>()
{
    "One",
    "Two",
    "Three",
    "Four",
    "Five",
    "Six",
    "Seven",
    "Eight",
    "Nine",
    "Ten"
};

The result of this is that you can select items in both the combo box as well as the list box by typing the first letters of the strings. For example, if you first type an "s", the entry "Six" is selected. If you add an "e" quickly after that, "Seven" is selected. If you pause typing for approximately one second, the mechanism is reset and starts over from the beginning. Example: Type in "seve", then wait a second or longer before you add the "n". "Nine" will be selected.

This mechanism also works very well with virtualization and scrolls the items control to the correct item.

Explicitly specifying the search criteria

The reason this works out of the box is that the runtime tries to automatically determine an item's identity as the user types, which works pretty well for items with text representation (more on this below). You can however override this by explicitly specifying what property should be used to identify an item during the search. This is particularly useful if you have multiple potential properties that could be used, or if you want to use a property that is not even shown in the view. For example, let's say you have a list of articles. Each entry shows various information about this article, but for the incremental search you want to use a specific piece of information, like the article number (i.e. not the name). Or your list contains only images, but the user should still be able to select one by name (even though that name isn't even visible).

The property used for this is the TextSearch.TextPath attached property. Working with this property looks like:

<ComboBox ItemsSource="{Binding ImageItems}"
          TextSearch.TextPath="Name">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding Image}"
                   Stretch="None" />
        </DataTemplate>
    </ComboBox.ItemTemplate>                
</ComboBox>

As you can see, the search text path is set to "Name", a property of the bound data items, and even though that property is not used in the data template at all, it works very well for the incremental search.

Search Criteria Utilization Strategy

As I just said, a certain strategy is used by the runtime to determine an item's identity for searching. The order for this is:

  • The TextSearch.TextPath attached property (see above).
  • The DisplayMemberPath property of the items control.
  • The Text property if the item is a TextBlock or TextBox.
  • The Text property of a contained text control if the item is a ContentControl.
  • The ToString() method.

Limitations

Although it is great to finally have a feature like this built into Silverlight, it comes with several limitations, for example:

  • You cannot customize the involved properties (like the pause time until the mechanism is reset).
  • You cannot customize the search strategy (it's always a "starts with"-like behavior that cannot be switched to e.g. "contains").
  • The search always is case insensitive.
  • There's no possibility to perform more complex searches, for example based on multiple properties. In the above sample with an article list, you might want to let your users search on both the article number and name, which simply isn't possible. This would require a callback option or similar so you can plug in your custom logic.

For these more sophisticated scenarios, a good alternative always is the AutoCompleteBox, which I've come to think of as "the better ComboBox" in many cases anyway.

Tags: Silverlight · Silverlight 5