WPF ComboBoxes and the Up/Down Directional Keys
If you have a hankoring to capture the Up/Down directional keys on a WPF ComboBox, and you try using the KeyDown event you will be sorely disppointed. I recently discovered this painful experience and was in need for a solution – as VendAsta‘s User Experience Specialist Ultra Power Awesome Man Allan Wolinksi had a kick ass idea and I wanted a kick ass implementation of his idea. So I hunted and I prowled and I scoured this “Internet” thingy for a couple hours trying to find out why oh why the ComboBox’s KeyDown event ignores my Up/Down directional keys.
I found plenty of workarounds for WinForms, but I’ve left WinForms and never want to go back. I’m fresh, and hip, and “flashy” and I’m all about the WPF (because it’s actually awesome). So I continued my relentless hunting for the answer. Tick Tock goes my clock, until eventually I found the problem. The ComboBox handles those keys internally to toggle between ComboBoxItems and set the SelectedItem. As such it never propagates those keys to the KeyDown event. The solution, therefore, is to beat ComboBox to the punch and override the ComboBox’s OnPreviewKeyDown method in a subclassed implementation.
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
if(e.KeyDown == System.Windows.Input.Key.Down)
{
// perform awesomeness
}
else if(e.KeyDown == System.Windows.Input.Key.Up)
{
// perform more awesomeness
}
base.OnPreviewKeyDown(e);
}
The above does the trick. In my specific situation, I actually set the e.Handled=true in both the Key.Down and Key.Up blocks so that the ComboBox doesn’t continue with the KeyDown routed event (I had a very specific behaviour I wanted performed). If you want to do the same you can tweak the above code with the following changes.
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
if(e.KeyDown == System.Windows.Input.Key.Down)
{
e.Handled = true;
// perform awesomeness
}
else if(e.KeyDown == System.Windows.Input.Key.Up)
{
e.Handled = true;
// perform more awesomeness
}
else
{
base.OnPreviewKeyDown(e);
}
}
That’s the solution I came to. Perhaps you discovered a different solution. If so, I’d love to hear it, so leave a comment in the Comments section. Or, even better, do it in person by applying with VendAsta and we can do it in person – afterall, nothing’s better than working with people you can learn from.