Focus Navigation Using Enter Key

|

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.

0 comments: