I am working on a new Silverlight user interface version of Simplesite.net and, as anyone can imagine, that involves a good dive into Silverlight as a ‘Line Of Business’ application technology.
One of the problems I encountered was to make the Combo box control able to respond to Mouse Wheel messages.
After having searched on different blogs and web sites, I didn’t find a suitable solution and ended up by delving into the subject.
Some of the proposed solutions consisted in ‘bringing into view’ one of the combo box items to force the list to scroll up or down as required… that seemed a little bit like a good workaround but was not very efficient and had a bad visual aspect.
What is a Silverlight ComboBox?
One of the nice (and pedagogic) aspects in Expression Blend is to be able to edit any existent control template (right click the control, select Edit Template / Edit a copy).
In Expression Blend, a Control Template reveals all the components of the control… this helps to understand some of the internal mechanisms of the control and how to use them efficiently.
To know more about the ComboBox control, I used Blend to insert one somewhere, and selected to edit a copy of its template.
That revealed the main components of the control:
§ A Layout Grid, containing:
§ A border (content presenter border) containing the static part of the combobox;
§ A Popup containing a ScrollViewer which will display the items.
It now seems clear that the scroll problem should be handled at the ScrollViewer component.
The SetIsMouseWheelScrollingEnabled method of the ScrollViewer can simply be used to activate the Mouse Wheel message handling for this component.
The solution
I saved my template to the application resources (App.xaml) with x:key=”combo_box_template”
<!-- ************* scrollable combo box template *******************************-->
<ControlTemplate x:Key="combo_box_template" TargetType="ComboBox">
I then created a class named ScrollableComboBox deriving from ComboBox
The control template is loaded and applied at class’s instantiation… and Mouse Wheel handling activated on the corresponding ScrollViewer component.
public partial class ScrollableComboBox : ComboBox
{
protected ScrollViewer m_scroll_viewer = null;
public ScrollableComboBox()
{
this.Style = (Style) App.Current.Resources["ScrollableComboBoxStyle"];
this.Template = (ControlTemplate) App.Current.Resources["combo_box_template"];
this.ApplyTemplate();
m_scroll_viewer = (ScrollViewer)GetTemplateChild("ScrollViewer");
if (m_scroll_viewer != null)
{
m_scroll_viewer.SetIsMouseWheelScrollingEnabled(true);
}
}
Surprisingly, that is all we need to activate scrolling on a Silverlight ComboBox!
We can now insert a ScrollableComboBox anywhere we need.