Some days ago someone in the Silverlight forums asked about how an auto-complete box that highlights the matched parts of potential hits could be made. Something like:
There is no built-in feature for this in the AutoCompleteBox and I didn't have a simple answer to that question. However I found it an interesting topic and a useful feature, so I decided to put some research in it as soon as I have some time. As it happens, I just had that time, and the result is this blog post :-). As always you can download the full source code at the end of the post.
Preliminary consideration
When I thought about the problem and the fact that you can put virtually everything into an auto-complete box item (it fully supports data templates for its items, see my article on the control here), I realized that this cannot be an extension of the control itself, but has to be a separate element, like a custom text block that can be used within the item template of an auto-complete box. At first I wanted to do exactly that, create a custom text block, but that class is sealed; so I had to use a user control that wraps a text block instead. Here is what I did.
A custom text block user control
The idea was to use multiple runs in a single text block, with a font weight of bold for the highlighted parts, and normal runs for the rest. To this end, the item text potentially needs to be split into several fragments first. To accomplish this, the following pieces of information are needed:
- The text to process.
- The filter string.
- The filter mode the auto-complete box is using.
Obviously all of this has to come from the auto-complete box control, so the user control I created has dependency properties, one for each of these three pieces, that can be used for data binding in XAML to retrieve these values automatically. Like that:
<sdk:AutoCompleteBox x:Name="ContainsAutoCompleteBox"
ItemsSource="{Binding Items}"
Width="300"
FilterMode="Contains"
MinimumPrefixLength="2">
<sdk:AutoCompleteBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<local:HighlightingTextBlock Text="{Binding}"
HighlightedText="{Binding Text, ElementName=ContainsAutoCompleteBox}"
FilterMode="{Binding FilterMode, ElementName=ContainsAutoCompleteBox}" />
</StackPanel>
Read more: Mister Goodcat