Общие сведения о фокусеFocus Overview

Существует два основных понятия, относящихся к фокусу в WPFWPF: фокус клавиатуры и логический фокус.In WPFWPF there are two main concepts that pertain to focus: keyboard focus and logical focus. Фокус клавиатуры ссылается на элемент, получающий ввод с клавиатуры, а логический фокус ссылается на элемент в области фокуса, имеющий фокус.Keyboard focus refers to the element that receives keyboard input and logical focus refers to the element in a focus scope that has focus. Эти понятия подробно освещаются в этом обзоре.These concepts are discussed in detail in this overview. Важно понимать разницу между этими понятиями, чтобы создавать сложные приложения с несколькими областями, в которых можно получить фокус.Understanding the difference in these concepts is important for creating complex applications that have multiple regions where focus can be obtained.

Основные классы, участвующие в управлении фокусом являются Keyboard класс, FocusManager класс и базовых элементов классы, такие как UIElement и ContentElement.The major classes that participate in focus management are the Keyboard class, the FocusManager class, and the base element classes, such as UIElement and ContentElement. Дополнительные сведения о базовых элементах см. в разделе Общие сведения о базовых элементах.For more information about the base elements, see the Base Elements Overview.

Keyboard Класс занимается в основном с фокусом клавиатуры и FocusManager занимается в основном с логическим фокусом, однако это не является абсолютным.The Keyboard class is concerned primarily with keyboard focus and the FocusManager is concerned primarily with logical focus, but this is not an absolute distinction. Элемент, имеющий фокус клавиатуры, также будет иметь логический фокус, но элемент, имеющий логический фокус, не обязательно будет иметь фокус клавиатуры.An element that has keyboard focus will also have logical focus, but an element that has logical focus does not necessarily have keyboard focus. Это видно при использовании Keyboard классу задать элемент, имеющий фокус клавиатуры, он также устанавливает логический фокус на элемент.This is apparent when you use the Keyboard class to set the element that has keyboard focus, for it also sets logical focus on the element.

Фокус клавиатурыKeyboard Focus

Фокус клавиатуры относится к элементу, получающему ввод с клавиатуры.Keyboard focus refers to the element that is currently receiving keyboard input. На всем рабочем столе может быть только один элемент, в котором находится фокус клавиатуры.There can be only one element on the whole desktop that has keyboard focus. В WPFWPF, будет иметь элемент, имеющий фокус клавиатуры IsKeyboardFocused присвоено true.In WPFWPF, the element that has keyboard focus will have IsKeyboardFocused set to true. Статическое свойство FocusedElement на Keyboard класс получает элемент, который в данный момент имеет фокус клавиатуры.The static property FocusedElement on the Keyboard class gets the element that currently has keyboard focus.

Чтобы элемент мог получить фокус клавиатуры Focusable и IsVisible свойства базовых элементов должно быть присвоено true.In order for an element to obtain keyboard focus, the Focusable and the IsVisible properties on the base elements must be set to true. Некоторые классы, такие как Panel базового класса, имеют Focusable присвоено false по умолчанию; таким образом, необходимо задать Focusable для true Если требуется, чтобы элемент мог получить фокус клавиатуры.Some classes, such as the Panel base class, have Focusable set to false by default; therefore, you must set Focusable to true if you want such an element to be able to obtain keyboard focus.

Фокус клавиатуры можно получить с помощью взаимодействия пользователя с ИПUI, например перехода к элементу или щелчка мышью определенных элементов.Keyboard focus can be obtained through user interaction with the ИПUI, such as tabbing to an element or clicking the mouse on certain elements. Фокус клавиатуры также могут быть получены программно с помощью Focus метод Keyboard класса.Keyboard focus can also be obtained programmatically by using the Focus method on the Keyboard class. Focus Метод пытается передать фокус клавиатуры для указанного элемента.The Focus method attempts to give the specified element keyboard focus. Возвращаемый элемент — это элемент, имеющий фокус клавиатуры, который может отличаться от запрошенного, если старый или новый объект фокуса блокирует запрос.The returned element is the element that has keyboard focus, which might be a different element than requested if either the old or new focus object block the request.

В следующем примере используется Focus метод, чтобы установить фокус на Button.The following example uses the Focus method to set keyboard focus on a Button.

private void OnLoaded(object sender, RoutedEventArgs e)
{
    // Sets keyboard focus on the first Button in the sample.
    Keyboard.Focus(firstButton);
}
Private Sub OnLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
    ' Sets keyboard focus on the first Button in the sample.
    Keyboard.Focus(firstButton)
End Sub

IsKeyboardFocused Свойство в классах базовых элементов получает значение, указывающее, имеет ли элемент фокус клавиатуры.The IsKeyboardFocused property on the base element classes gets a value indicating whether the element has keyboard focus. IsKeyboardFocusWithin Свойство в классах базовых элементов получает значение, указывающее, имеет ли элемент или один из его визуальных дочерних элементов фокус клавиатуры.The IsKeyboardFocusWithin property on the base element classes gets a value indicating whether the element or any one of its visual child elements has keyboard focus.

При настройке начального фокуса при запуске приложения, элемент должен получить фокус должен быть в визуальном дереве первоначального окна, загружаемого этим приложением, и элемент должен иметь Focusable и IsVisible присвоено true.When setting initial focus at application startup, the element to receive focus must be in the visual tree of the initial window loaded by the application, and the element must have Focusable and IsVisible set to true. Рекомендуется устанавливать исходный фокус начинается в Loaded обработчик событий.The recommended place to set initial focus is in the Loaded event handler. Объект Dispatcher обратного вызова также можно путем вызова Invoke или BeginInvoke.A Dispatcher callback can also be used by calling Invoke or BeginInvoke.

Логический фокусLogical Focus

Логический фокус относится к FocusManager.FocusedElement в области фокуса.Logical focus refers to the FocusManager.FocusedElement in a focus scope. Область фокуса — элемент, который отслеживает FocusedElement внутри своей области.A focus scope is an element that keeps track of the FocusedElement within its scope. Когда фокус клавиатуры покидает область фокуса, элемент с фокусом теряет фокус клавиатуры, но сохраняет логический фокус.When keyboard focus leaves a focus scope, the focused element will lose keyboard focus but will retain logical focus. При возвращении фокуса клавиатуры в область фокуса элемент с логическим фокусом получит фокус клавиатуры.When keyboard focus returns to the focus scope, the focused element will obtain keyboard focus. Это позволяет переносить фокус клавиатуры между несколькими областями фокуса, но гарантирует, что элемент с фокусом в области фокуса останется элементом с фокусом клавиатуры, когда фокус вернется в эту область.This allows for keyboard focus to be changed between multiple focus scopes but ensures that the focused element in the focus scope regains keyboard focus when focus returns to the focus scope.

В приложении может быть несколько элементов, имеющих логический фокус, но в отдельной области фокуса может быть только один элемент, имеющий логический фокус.There can be multiple elements that have logical focus in an application, but there may only be one element that has logical focus in a particular focus scope.

Элемент, имеющий фокус клавиатуры, имеет логический фокус для области фокуса, которой он принадлежит.An element that has keyboard focus has logical focus for the focus scope it belongs to.

Элемент может быть включен в область фокуса в Язык XAMLExtensible Application Markup Language (XAML) , задав FocusManager присоединенное свойство IsFocusScope для true.An element can be turned into a focus scope in Язык XAMLExtensible Application Markup Language (XAML) by setting the FocusManager attached property IsFocusScope to true. В коде, элемент может быть включен в область фокуса путем вызова SetIsFocusScope.In code, an element can be turned into a focus scope by calling SetIsFocusScope.

В нижеследующем примере StackPanel в область фокуса, задав IsFocusScope вложенного свойства зависимостей.The following example makes a StackPanel into a focus scope by setting the IsFocusScope attached property.

<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);
Dim focuseScope2 As New StackPanel()
FocusManager.SetIsFocusScope(focuseScope2, True)

GetFocusScope Возвращает область фокуса для заданного элемента.GetFocusScope returns the focus scope for the specified element.

Классы в WPFWPF являются областями фокуса по умолчанию Window, MenuItem, ToolBar, и ContextMenu.Classes in WPFWPF which are focus scopes by default are Window, MenuItem, ToolBar, and ContextMenu.

GetFocusedElement Получает элемент с фокусом для заданной области фокуса.GetFocusedElement gets the focused element for the specified focus scope. SetFocusedElement Задает элемент с фокусом в заданной области фокуса.SetFocusedElement sets the focused element in the specified focus scope. SetFocusedElement обычно используется для задания исходного элемента с фокусом.SetFocusedElement is typically used to set the initial focused element.

В следующем примере элемент с фокусом задается в области фокуса и возвращает элемент с фокусом для области фокуса.The following example sets the focused element on a focus scope and gets the focused element of a focus scope.

// Sets the focused element in focusScope1
// focusScope1 is a StackPanel.
FocusManager.SetFocusedElement(focusScope1, button2);

// Gets the focused element for focusScope 1
IInputElement focusedElement = FocusManager.GetFocusedElement(focusScope1);
' Sets the focused element in focusScope1
' focusScope1 is a StackPanel.
FocusManager.SetFocusedElement(focusScope1, button2)

' Gets the focused element for focusScope 1
Dim focusedElement As IInputElement = FocusManager.GetFocusedElement(focusScope1)

Навигация с помощью клавиатурыKeyboard Navigation

KeyboardNavigation Класс отвечает за реализацию навигации с фокусом клавиатуры по умолчанию, когда нажата одна из клавиш навигации.The KeyboardNavigation class is responsible for implementing default keyboard focus navigation when one of the navigation keys is pressed. Клавиши навигации: Клавиши TAB, SHIFT + TAB, CTRL + TAB, CTRL + SHIFT + TAB, Стрелка вверх, Стрелка вниз, Стрелка влево и Стрелка вправо.The navigation keys are: TAB, SHIFT+TAB, CTRL+TAB, CTRL+SHIFT+TAB, UPARROW, DOWNARROW, LEFTARROW, and RIGHTARROW keys.

Поведение навигации контейнера навигации можно изменить при помощи вложенных KeyboardNavigation свойства TabNavigation, ControlTabNavigation, и DirectionalNavigation.The navigation behavior of a navigation container can be changed by setting the attached KeyboardNavigation properties TabNavigation, ControlTabNavigation, and DirectionalNavigation. Эти свойства имеют тип KeyboardNavigationMode и возможные значения: Continue, Local, Contained, Cycle, Once, и None.These properties are of type KeyboardNavigationMode and the possible values are Continue, Local, Contained, Cycle, Once, and None. Значение по умолчанию — Continue, который означает, что элемент не является контейнером навигации.The default value is Continue, which means the element is not a navigation container.

В следующем примере создается Menu с количеством MenuItem объектов.The following example creates a Menu with a number of MenuItem objects. TabNavigation Присоединенное свойство имеет значение Cycle на Menu.The TabNavigation attached property is set to Cycle on the Menu. При изменении фокуса с помощью клавиши tab в Menu, фокус перемещается из каждого элемента, и при достижении последнего элемента переходит к первому элементу.When focus is changed using the tab key within the Menu, focus will move from each element and when the last element is reached focus will return to the first element.

<Menu KeyboardNavigation.TabNavigation="Cycle">
  <MenuItem Header="Menu Item 1" />
  <MenuItem Header="Menu Item 2" />
  <MenuItem Header="Menu Item 3" />
  <MenuItem Header="Menu Item 4" />
</Menu>
Menu navigationMenu = new Menu();
MenuItem item1 = new MenuItem();
MenuItem item2 = new MenuItem();
MenuItem item3 = new MenuItem();
MenuItem item4 = new MenuItem();

navigationMenu.Items.Add(item1);
navigationMenu.Items.Add(item2);
navigationMenu.Items.Add(item3);
navigationMenu.Items.Add(item4);

KeyboardNavigation.SetTabNavigation(navigationMenu, 
    KeyboardNavigationMode.Cycle);
Dim navigationMenu As New Menu()
Dim item1 As New MenuItem()
Dim item2 As New MenuItem()
Dim item3 As New MenuItem()
Dim item4 As New MenuItem()

navigationMenu.Items.Add(item1)
navigationMenu.Items.Add(item2)
navigationMenu.Items.Add(item3)
navigationMenu.Items.Add(item4)

KeyboardNavigation.SetTabNavigation(navigationMenu, KeyboardNavigationMode.Cycle)

Дополнительные API для работы с фокусом, MoveFocus и PredictFocus.Additional API to work with focus are MoveFocus and PredictFocus.

MoveFocus изменения фокуса к следующему элементу в приложении.MoveFocus changes focus to the next element in the application. Объект TraversalRequest используется для указания направления.A TraversalRequest is used to specify the direction. FocusNavigationDirection Передается MoveFocus указывает, можно перемещать фокус разных направлениях, таких как First, Last, Up и Down.The FocusNavigationDirection passed to MoveFocus specifies the different directions focus can be moved, such as First, Last, Up and Down.

В следующем примере используется MoveFocus Чтобы изменить элемент с фокусом.The following example uses MoveFocus to change the focused element.

// Creating a FocusNavigationDirection object and setting it to a
// local field that contains the direction selected.
FocusNavigationDirection focusDirection = _focusMoveValue;

// MoveFocus takes a TraveralReqest as its argument.
TraversalRequest request = new TraversalRequest(focusDirection);

// Gets the element with keyboard focus.
UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;

// Change keyboard focus.
if (elementWithFocus != null)
{
    elementWithFocus.MoveFocus(request);
}
' Creating a FocusNavigationDirection object and setting it to a
' local field that contains the direction selected.
Dim focusDirection As FocusNavigationDirection = _focusMoveValue

' MoveFocus takes a TraveralReqest as its argument.
Dim request As New TraversalRequest(focusDirection)

' Gets the element with keyboard focus.
Dim elementWithFocus As UIElement = TryCast(Keyboard.FocusedElement, UIElement)

' Change keyboard focus.
If elementWithFocus IsNot Nothing Then
    elementWithFocus.MoveFocus(request)
End If

PredictFocus Возвращает объект, который должен получить фокус, если фокус должен быть изменен.PredictFocus returns the object which would receive focus if focus were to be changed. В настоящее время только Up, Down, Left, и Right поддерживаются PredictFocus.Currently, only Up, Down, Left, and Right are supported by PredictFocus.

События фокусаFocus Events

События, связанные с фокусом клавиатуры: PreviewGotKeyboardFocus, GotKeyboardFocus и PreviewLostKeyboardFocus, LostKeyboardFocus.The events related to keyboard focus are PreviewGotKeyboardFocus, GotKeyboardFocus and PreviewLostKeyboardFocus, LostKeyboardFocus. События определяются как вложенные события в Keyboard класса, но более легко доступны как эквивалентные перенаправленные события в классах базовых элементов.The events are defined as attached events on the Keyboard class, but are more readily accessible as equivalent routed events on the base element classes. Дополнительные сведения о событиях см. в разделе Общие сведения о перенаправленных событиях.For more information about events, see the Routed Events Overview.

GotKeyboardFocus вызывается, когда элемент получает фокус клавиатуры.GotKeyboardFocus is raised when the element obtains keyboard focus. LostKeyboardFocus вызывается, когда элемент теряет фокус клавиатуры.LostKeyboardFocus is raised when the element loses keyboard focus. Если PreviewGotKeyboardFocus событий или PreviewLostKeyboardFocusEvent событие обрабатывается и Handled присваивается true, а затем фокус не изменится.If the PreviewGotKeyboardFocus event or the PreviewLostKeyboardFocusEvent event is handled and Handled is set to true, then focus will not change.

В следующем примере подключается GotKeyboardFocus и LostKeyboardFocus обработчики событий для TextBox.The following example attaches GotKeyboardFocus and LostKeyboardFocus event handlers to a TextBox.

<Border BorderBrush="Black" BorderThickness="1"
        Width="200" Height="100" Margin="5">
  <StackPanel>
    <Label HorizontalAlignment="Center" Content="Type Text In This TextBox" />
    <TextBox Width="175"
             Height="50" 
             Margin="5"
             TextWrapping="Wrap"
             HorizontalAlignment="Center"
             VerticalScrollBarVisibility="Auto"
             GotKeyboardFocus="TextBoxGotKeyboardFocus"
             LostKeyboardFocus="TextBoxLostKeyboardFocus"
             KeyDown="SourceTextKeyDown"/>
  </StackPanel>
</Border>

Когда TextBox получает фокус клавиатуры, Background свойство TextBox изменяется на LightBlue.When the TextBox obtains keyboard focus, the Background property of the TextBox is changed to LightBlue.

private void TextBoxGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    TextBox source = e.Source as TextBox;

    if (source != null)
    {
        // Change the TextBox color when it obtains focus.
        source.Background = Brushes.LightBlue;

        // Clear the TextBox.
        source.Clear();
    }
}
Private Sub TextBoxGotKeyboardFocus(ByVal sender As Object, ByVal e As KeyboardFocusChangedEventArgs)
    Dim source As TextBox = TryCast(e.Source, TextBox)

    If source IsNot Nothing Then
        ' Change the TextBox color when it obtains focus.
        source.Background = Brushes.LightBlue

        ' Clear the TextBox.
        source.Clear()
    End If
End Sub

Когда TextBox теряет фокус клавиатуры, Background свойство TextBox изменяется обратно на белое.When the TextBox loses keyboard focus, the Background property of the TextBox is changed back to white.

private void TextBoxLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    TextBox source = e.Source as TextBox;

    if (source != null)
    {
        // Change the TextBox color when it loses focus.
        source.Background = Brushes.White;

        // Set the  hit counter back to zero and updates the display.
        this.ResetCounter();
    }
}
Private Sub TextBoxLostKeyboardFocus(ByVal sender As Object, ByVal e As KeyboardFocusChangedEventArgs)
    Dim source As TextBox = TryCast(e.Source, TextBox)

    If source IsNot Nothing Then
        ' Change the TextBox color when it loses focus.
        source.Background = Brushes.White

        ' Set the  hit counter back to zero and updates the display.
        Me.ResetCounter()
    End If
End Sub

События, связанные с логическим фокусом: GotFocus и LostFocus.The events related to logical focus are GotFocus and LostFocus. Эти события определяются в FocusManager как Прикрепленные события, но FocusManager не предоставляет оболочки событий среды CLR.These events are defined on the FocusManager as attached events, but the FocusManager does not expose CLR event wrappers. UIElement и ContentElement предоставляют эти события более удобным.UIElement and ContentElement expose these events more conveniently.

См. такжеSee also