1. Demand
After loading the first input box or let the focus is a very basic functions, such as the typical "Login" dialog. In general the "Login" dialog to load the "User Name" should immediately focus, users only need to enter a user name, click Tab
, and then enter the password, click Enter to complete the login.
To make a control gets the focus when loading in WPF should be very simple, just call after the Loaded event Focus()
on the line. But sometimes form is dynamically added or form elements based on the first show or hide certain conditions, it's difficult to simply let the first control has the focus.
To achieve this I created a class called FocusService tool, this article describes the principles and use of this class, as well as add some knowledge WPF focus.
2. Implement
public static readonly DependencyProperty IsAutoFocusProperty =
DependencyProperty.RegisterAttached("IsAutoFocus", typeof(bool), typeof(FocusService), new PropertyMetadata(default(bool), OnIsAutoFocusChanged));
public static bool GetIsAutoFocus(DependencyObject obj) => (bool)obj.GetValue(IsAutoFocusProperty);
public static void SetIsAutoFocus(DependencyObject obj, bool value) => obj.SetValue(IsAutoFocusProperty, value);
private static void OnIsAutoFocusChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
var oldValue = (bool)args.OldValue;
var newValue = (bool)args.NewValue;
if (oldValue == newValue)
{
return;
}
if (obj is FrameworkElement target)
{
target.Loaded -= OnTargetLoaded;
if (newValue)
{
target.Loaded += OnTargetLoaded;
}
}
}
private static void OnTargetLoaded(object sender, RoutedEventArgs e)
{
var element = sender as FrameworkElement;
if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(element))
return;
var request = new TraversalRequest(FocusNavigationDirection.Next);
element.MoveFocus(request);
}
The above is FocusService code, it uses the additional attribute controls whether IsAutoFocus automatically focus, in order to make additional attributes may be controlled in XAML. This additional attribute can be used not only in the Control, can also be used on other UI elements like Grid. In the Form is provided with DefaultStyle Setter set default values, mentioned before additional properties and general properties are not dependent set default values in the code.
<Setter Property="local:FocusService.IsAutoFocus"
Value="True" />
MoveFocus
In FrameworkElement on the IsAutoFocus
attached property is set to True then (False does not handle), this FrameworkElement will be called Loaded event MoveFocus function will move the keyboard focus to itself VisualTree the first element can receive focus. Specific operations generally, MoveFocus is to use a depth-first traversal of the way VisualTree, find the first IsTabStob, Focusable and IsVisible are elements of True and call Keyboard.Focus
functions. The so-called "first" is basically intuitive and user understanding of the same.
DesignerProperties.GetIsInDesignMode
DesignerProperties.GetIsInDesignMode method for determining whether the element running in the designer. VisualStudio designer too strong, almost WYSIWYG, most of the code can be run in design view. If it is judged OnTargetLoaded running operation is not performed later in the design, a design is to avoid views are refreshed every time it receives the focus.
VisualStudio designer is really very strong, but sometimes it will program because the data is not ready, or a variety of reasons being given, if you encounter an error designer and do not want to deal with specific reasons can be considered simple and crude to use DesignerProperties.GetIsInDesignMode
judgment and direct return.
3. Two types of focus
As a supplement knowledge, this article will briefly explain the focus of WPF.
3.1 keyboard focus
Refers to the current keyboard focus is receiving keyboard input UI elements. On the whole desktop, there can be only one element with keyboard focus. In order to make the UI elements get focus, Focusable and IsVisible it must be True. Typically, for a non-default attribute values Focusable control class is False.
Keyboard class may be used to handle the keyboard focus, as follows:
Keyboard.Focus(FirstTextBox);
Focus function If successful, UI elements IsKeyboardFocused is set to True, and it is the parent element itself or VisualTree levels IsKeyboardFocusWithin will become True.
Of course, if the UI elements not loaded onto VisualTree Focus function does not execute successfully, it is usually only executed Focus function after the Loaded event.
3.2 logical focus
Refers to the logical focus of FocusScope FocusManager.FocusedElement , there may be a plurality of application element gets logical focus, but only one element of the keyboard focus is obtained. Element keyboard focus while also gets logical focus.
FocusScope
FocusScope by FocusManager.IsFocusScope change.
<StackPanel Name="focusScope1"
FocusManager.IsFocusScope="True"
Height="200" Width="200">
<Button Name="button1" Height="50" Width="50"/>
<Button Name="button2" Height="50" Width="50"/>
</StackPanel>
StackPanel focuseScope2 = new StackPanel();
FocusManager.SetIsFocusScope(focuseScope2, true);
FocusedElement
FocusManager management logic is further configured to focus, which uses GetFocusedElement (DependencyObject) acquires focus logic element FocusScope obtained using SetFocusedElement (DependencyObject, IInputElement) the focus is set to logic element.
3.3 Window logical focus of
Window default FocusScope, it is set to True (not provided in the DefaultStyle) in the static constructor function IsFocusScope:
FocusManager.IsFocusScopeProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(true));
When loading Window (or Window itself is activated), which will allow similar code elements Window logical focus of focus.
DependencyObject doContent = Content as DependencyObject;
if (doContent != null)
{
IInputElement focusedElement = FocusManager.GetFocusedElement(doContent) as IInputElement;
if (focusedElement != null)
focusedElement.Focus();
}
4. Conclusion
In fact, no class can, anyway, the code is simple, just want to pass this class was introduced to the use of additional properties and Focus.
Do custom focus manager to do, especially now, because a lot of designers, product managers, developers have a wealth of experience in mobile application development and design, due to the slightly different logical keyboard navigation on your phone and desktop applications, so the keyboard navigation details can easily be overlooked.
Often, though not with the use of easily feel someone will put forward the demand, developers always attentive to getting good keyboard navigation.
5. Reference
FocusManager Class (System.Windows.Input) Microsoft Docs
Keyboard.Focus(IInputElement) Method (System.Windows.Input) Microsoft Docs
UIElement.MoveFocus(TraversalRequest) Method (System.Windows) Microsoft Docs