Moving focus between UI elements using Enter key is probably one of the controversial features of user interaction design, personally I think it has its own usage, and is a great complement to tab navigation, here is the two techniques of implementing enter navigation I learnt from WPF MSDN forum, both of the two methods need you to first hook up to interesting controls' KeyDown event, imagine you have such piece of XAML:
<Window x:Class="EnterNavigationDemo.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Login" Width="300" Height="200" ResizeMode="NoResize"
>
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Width" Value="60"/>
<Setter Property="Margin" Value="4"/>
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Width" Value="160"/>
<Setter Property="Margin" Value="4"/>
</Style>
<Style TargetType="{x:Type PasswordBox}">
<Setter Property="Width" Value="160"/>
<Setter Property="Margin" Value="4"/>
</Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Margin" Value="4"/>
</Style>
</Window.Resources>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Name="documentRoot">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Target="{Binding ElementName=txtDomainName}" Content="_Domain:" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="txtDomainName" Grid.Column="1" Grid.Row="0"/>
<Label Target="{Binding ElementName=txtUserName}" Content="_User:" Grid.Column="0" Grid.Row="1"/>
<TextBox Name="txtUser" Grid.Column="1" Grid.Row="1"/>
<Label Target="{Binding ElementName=txtPasswrod}" Content="_Passwrod:" Grid.Column="0" Grid.Row="2"/>
<PasswordBox Name="txtPasswrod" Grid.Column="1" Grid.Row="2"/>
<StackPanel Grid.Row="3" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="_Login" Name="loginButton" IsDefault="True"/>
<Button Content="_Cancel" Name="cancelButton" IsCancel="True"/>
</StackPanel>
</Grid>
</Window>
In the code behind file, you can achieve enter navigation using the following methods:
public partial class Window1 : System.Windows.Window
{
public Window1()
{
InitializeComponent();
this.documentRoot.AddHandler(TextBox.KeyDownEvent, new KeyEventHandler(documentRoot_KeyDown));
this.loginButton.Click += new RoutedEventHandler(loginButton_Click);
this.cancelButton.Click += new RoutedEventHandler(cancelButton_Click);
}
private void cancelButton_Click(Object sender, RoutedEventArgs e)
{
MessageBox.Show("Cancel button is clicked");
}
private void loginButton_Click(Object sender, RoutedEventArgs e)
{
MessageBox.Show("Login button is clicked");
}
private void documentRoot_KeyDown(Object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
UIElement focusedElement = Keyboard.FocusedElement as UIElement;
if (focusedElement != null)
{
focusedElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
e.Handled = true;
}
}
}
you can also achieve this by modifying the key down event handler to add the following code:
private void documentRoot_KeyDown(Object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
e.Handled = true;
KeyEventArgs args = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Tab);
args.RoutedEvent = Keyboard.KeyDownEvent;
InputManager.Current.ProcessInput(args);
}
}
You can see that I add two buttons on the window, my initial thought is that I want enter navigate between the three TextBoxes, but I still want to tab navigate to the buttons, and the above code finally ends up working in the way I desire.