17 December 2008
My "TextSearchListBox" control for Silverlight derives from ListBox and enables the text searching capability that many of us have come to expect in applications. The experience is a great improvement over the standard ListBox, and was simple enough to build out this evening.
I've attached the complete project and source code and hope that you find it useful in your apps in one way or another.
When you give the list box control focus and type a character, the first item with the matching case insensitive prefix appears and is selected. For example, in the sample application attached to this post, I clicked on the list box control to give it focus, and then typed the letter 'c':
Pressed "c", Charlotte is selected.
If you're looking at a list of a thousand items, like a music playlist, this can be a time-saver. But you can also continue typing quickly, and even use the backspace to make corrections.
If I had quickly typed the letter "o" right after first letter, it would highlight the city of Columbus:
Press "c" and then quickly "o", Columbus is selected.
The control's searching logic is also able to intelligently handle repeated keypresses to move down the list. So, after typing either of the earlier samples, or just from the start, you can press the "d" key 5 times. It quickly will move the selection from Dallas all the way through to Detroit:
Press "d" 5 times to move through the other "d" words in the list box.
This is a great feature and it was relatively easy to implement, especially given the similarities to a typical auto complete control.
I'll be honest, before I joined Microsoft several years ago, I didn't know that you could type in a standard list box in a useful way. It's one of those hidden gems that I have used so many times since the insightful day I learned of the capability.
The string value is figured out very differently than in WPF. Since ListBox supports rich data items, there's no easy way in Silverlight for the TextSearchListBox to know what the underlying text value is, and I didn't want to pollute the example with any kind of binding or display member path work.
Instead, the logic for this example is super simple: the ToString() operator is used for each item.
That means that if you use something like a standard business object, the text search won't really work out so well - the search algorithm would think that every item is the text "YourNamespace.YourBusinessObject", if YourBusinessObject was the CLR class. In the attached sample application, I've simply bound to a list of strings. If you don't own the object to be able to override the ToString method, you can wrap the items in a derived or adapter class.
If you've used the AutoCompleteBox control in the Silverlight Toolkit, you'll notice that this is slightly different. For the auto complete control, I wanted to provide the best experience for item-to-string conversions, so there is also an exposed IValueConverter property called "Converter" that is tried before the ToString fallback.
Simply download the source code or drop the TextSearchListBox.cs file into your Silverlight application, update the namespace, and you're ready to go.
Here's the XAML for the sample application:
<UserControl x:Class="YourNamespace.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:YourNamespace" Width="315" Height="340"> <Grid x:Name="LayoutRoot" Margin="5"> <Border BorderBrush="#11999999" BorderThickness="1" CornerRadius="3"> <Border BorderBrush="#22999999" BorderThickness="1" CornerRadius="3"> <Border BorderBrush="#33999999" BorderThickness="1" CornerRadius="3"> <local:TextSearchListBox x:Name="listBox1" /> </Border> </Border> </Border> </Grid> </UserControl>
And the page code behind:
using System.Linq; using System.Windows.Controls; using Microsoft.Windows.Controls.Samples; namespace YourNamespace { public partial class Page : UserControl { public Page() { InitializeComponent(); Loaded += (s, e) => listBox1.ItemsSource = (from n in Airport.SampleAirports orderby n.City select n.City).Distinct(); } } }
Looking for a similar text searching control? Download the Silverlight Toolkit December 2008 release and check out the AutoCompleteBox control - a text box that provides a rich drop-down with completion suggestions.
Hope this helps! Let me know if you find this useful.
Jeff Wilcox is a Software Engineer at Microsoft in the Open Source Programs Office (OSPO), helping Microsoft engineers use, contribute to and release open source at scale.