Introduction
Probably you know the search box from the Apple menu, either from Mac OS X itself or, like me, from pictures. I think that's a pretty cool feature and so I developed an extensible WPF control for searching through all menu items.
Screenshot of the search box in action
Background
The project mainly consists of two classes, MenuSearchBoxBase
and MenuSearchBox
. MenuSearchBoxBase
is abstract and does not contain the code for matching and collecting items and for displaying the results but only abstract functions for this. MenuSearchBox
is a basic implementation of the menu search box.
The search is done in 4 steps:
- Clearing
protected abstract void ClearResults();
In this step, the displayed results are cleared. Notice: The
function is also called, when no results have been displayed before.
- Collecting
protected abstract IEnumerable<Control> Collect();
In this step the menu items to search through are collected. Normally, these are all menu items of the menu containing the search box.
- Matching
protected abstract double Match(Control control, string search);
This is function is called for every control collected in the step before. The result is a match score describing how much the control matches the search the user typed. A match score of 0 means that the control does not match the search; these results are not displayed.
- Displaying
protected abstract void DisplayResults(IEnumerable<Control> results);
This function displays the results that were collected and have a match score greater than 0. The results are presorted by the match score; the match score is not accessible in the function.
Using the code
Because you can insert not just MenuItem
s but any control into a menu, you can simply insert the search box in the menu after referencing the assembly and creating a namespace definition in the XAML file:
<Window x:Class="Demo.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:msb="clr-namespace:MenuSearch;assembly=MenuSearchBox">
-->
<Menu>
<MenuItem Header="Help">
<msb:MenuSearchBox />-->
</MenuItem>
</Menu>
</Window>
Points of Interest
Cloning in WPF?
Because I didn't find a way to clone controls in WPF (if there is one, tell me), I had to move all controls to the result list and move them back after closing the menu. This required me to exclude items from the submenu containing the search box from the search, otherwise it would look pretty weird, because the control would disappeare and show up in the result list.
History
Thursday April 10th (my birthday :): Article published.