Enter-to-Tab in WPF
Like many users of line-of-business applications, my own users just can't understand the Tab key. For them, pressing Enter on the keyboard shouldn't submit a form, it should just move their focus to the next control.
Back in the Windows Forms days there was a neat way to achieve this functionality: You caught the KeyDown event on each of your controls and used the SelectNextControl method to move focus to the next control. In WPF, however, there's no SelectNextControl method! So how do we do something similar?
The first trick to use in WPF is to handle the PreviewKeyDown event on all your data-entry controls in one hit, rather than having to declaratively handle it individually in each control. In my case I have all my controls inside a grid, so I simply declare my grid like this:
<Grid UIElement.PreviewKeyDown="Grid_PreviewKeyDown">
What I'm doing here is telling the grid that any child control that descends from UIElement (and that includes TextBoxes and ComboBoxes) should have their PreviewKeyDown event handled by a common method called Grid_PreviewKeyDown.
So now we have caught key presses on our controls. Now, how do we tell the window to move its focus to the next available control? We don't have SelectNextControl, but we have a new method with a similar function: MoveFocus!
private void Grid_PreviewKeyDown(object sender, KeyEventArgs e)
{
var uie = e.OriginalSource as UIElement;
if (e.Key == Key.Enter)
{
e.Handled = true;
uie.MoveFocus(
new TraversalRequest(
FocusNavigationDirection.Next));
}
}
So here we're getting the control that sent us the PreviewKeyDown event, and calling its MoveFocus method to shift the focus to the next control!
So now you have no excuses! WPF can be used for line-of-business style applications after all!

# Trackback from Enter to Tab as an Attached Property on 18/08/2008 11:57 AM
Comments
# Paul Stovell
25/03/2008 6:07 PM
Good example Matt. I wonder if it could be implemented as an attached dependency property:
<TextBox extended:KeyboardNavigation.EnterActsAsTab="True" />
In the setter method, you could get the control, then wire up the event handler.
Then you could set it via styles on the various editable controls.
# mabster
25/03/2008 6:23 PM
To be honest, Paul, I wondered myself whether it could be an attached property but wasn't sure how to implement it.
I also wonder whether it could be an "attached event". Perhaps catch PreviewKeyDown on ALL UIElements but then check if the attached "EnterActsAsTab" property is true before running the event handler code.
# Kashif
14/05/2008 7:55 PM
I am using Infragistics third party controls. Would these elements added to the UIElement collection as well?
# Emmanuel Huna
26/09/2008 6:42 AM
Private Sub LayoutRoot_PreviewKeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
Dim oUIElement As UIElement
Dim bIsMultiline As Boolean = False
Dim oTextBox As Controls.TextBox
If e.Key = Key.Enter Then
Try
oUIElement = CType(e.OriginalSource, UIElement)
Try
oTextBox = CType(oUIElement, Controls.TextBox)
If stit(UCase(oTextBox.Tag)) = cEDITORMULTILINE Then bIsMultiline = True
Catch ex As Exception
bIsMultiline = False
End Try
If Not (bIsMultiline) Then
e.Handled = True
oUIElement.MoveFocus(New TraversalRequest(FocusNavigationDirection.Next))
End If
Catch ex As Exception
End Try
End If
End Sub
Leave a Comment