Información general sobre el focoFocus Overview

En WPFWPF, hay dos conceptos principales relacionados con el foco: el foco de teclado y el foco lógico.In WPFWPF there are two main concepts that pertain to focus: keyboard focus and logical focus. El foco de teclado hace referencia al elemento que recibe la entrada del teclado, y el foco lógico hace referencia al elemento que tiene el foco en un ámbito de foco.Keyboard focus refers to the element that receives keyboard input and logical focus refers to the element in a focus scope that has focus. Estos conceptos se describen con detalle en esta información general.These concepts are discussed in detail in this overview. Entender la diferencia entre estos conceptos es importante para crear aplicaciones complejas que tengan varias regiones donde se pueda obtener el foco.Understanding the difference in these concepts is important for creating complex applications that have multiple regions where focus can be obtained.

Las clases principales que participan en la administración del foco son la Keyboard (clase), el FocusManager clase y el elemento base, clases, como UIElement y 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. Para obtener más información sobre los elementos base, consulte Información general sobre los elementos base.For more information about the base elements, see the Base Elements Overview.

El Keyboard clase se ocupa principalmente del foco de teclado y el FocusManager se refiere a principalmente con el foco lógico, pero esto no es una distinción absoluta.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. Un elemento que tiene el foco de teclado también tendrá el foco lógico, pero un elemento que tiene el foco lógico no tendrá necesariamente el foco de teclado.An element that has keyboard focus will also have logical focus, but an element that has logical focus does not necessarily have keyboard focus. Esto es evidente cuando se usa el Keyboard clase para establecer el elemento que tiene el foco de teclado, para también establece el foco lógico en el elemento.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.

Foco de tecladoKeyboard Focus

El foco de teclado hace referencia al elemento que recibe actualmente la entrada del teclado.Keyboard focus refers to the element that is currently receiving keyboard input. Puede haber un único elemento en todo el escritorio que tenga el foco de teclado.There can be only one element on the whole desktop that has keyboard focus. En WPFWPF, el elemento que tiene el foco de teclado tendrá IsKeyboardFocused establecido en true.In WPFWPF, the element that has keyboard focus will have IsKeyboardFocused set to true. La propiedad estática FocusedElement en el Keyboard clase obtiene el elemento que tiene actualmente el foco de teclado.The static property FocusedElement on the Keyboard class gets the element that currently has keyboard focus.

Para un elemento obtenga el foco de teclado, el Focusable y IsVisible se deben establecer las propiedades de los elementos base en 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. Algunas clases, como el Panel clase base, tienen Focusable establecido en false de forma predeterminada; por lo tanto, debe establecer Focusable a true si desea que ese elemento pueda recibir el foco de teclado.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.

El foco de teclado puede obtenerse a través de la interacción del usuario con la IUUI, como desplazarse mediante la tecla TAB hasta un elemento o hacer clic con el mouse en determinados elementos.Keyboard focus can be obtained through user interaction with the IUUI, such as tabbing to an element or clicking the mouse on certain elements. El foco de teclado también puede obtenerse mediante programación utilizando la Focus método en el Keyboard clase.Keyboard focus can also be obtained programmatically by using the Focus method on the Keyboard class. El Focus método intenta dar el foco de teclado del elemento especificado.The Focus method attempts to give the specified element keyboard focus. El elemento devuelto es el elemento que tiene el foco de teclado, que puede ser un elemento diferente al solicitado si el objeto que tenía el foco antes o el que tiene el foco ahora bloquean la solicitud.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.

En el ejemplo siguiente se usa el Focus método para establecer el foco de teclado en un 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

El IsKeyboardFocused propiedad en las clases de elementos base Obtiene un valor que indica si el elemento tiene el foco de teclado.The IsKeyboardFocused property on the base element classes gets a value indicating whether the element has keyboard focus. El IsKeyboardFocusWithin propiedad en las clases de elementos base Obtiene un valor que indica si el elemento o cualquiera de sus elementos secundarios visuales tiene el foco de teclado.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.

Al establecer el foco inicial al iniciarse la aplicación, debe ser el elemento que se va a recibir el foco en el árbol visual de la ventana inicial cargada por la aplicación y debe tener el elemento Focusable y IsVisible establecido en 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. Es el lugar recomendado para establecer el foco inicial en el Loaded controlador de eventos.The recommended place to set initial focus is in the Loaded event handler. Un Dispatcher también se puede utilizar la devolución de llamada mediante una llamada a Invoke o BeginInvoke.A Dispatcher callback can also be used by calling Invoke or BeginInvoke.

Foco lógicoLogical Focus

Foco lógico hace referencia a la FocusManager.FocusedElement en un ámbito de foco.Logical focus refers to the FocusManager.FocusedElement in a focus scope. Un ámbito de foco es un elemento que realiza un seguimiento de la FocusedElement dentro de su ámbito.A focus scope is an element that keeps track of the FocusedElement within its scope. Cuando el foco de teclado sale de un ámbito de foco, el elemento enfocado pierde el foco de teclado, pero conserva el foco lógico.When keyboard focus leaves a focus scope, the focused element will lose keyboard focus but will retain logical focus. Cuando el foco de teclado vuelve al ámbito de foco, el elemento enfocado recibe el foco de teclado.When keyboard focus returns to the focus scope, the focused element will obtain keyboard focus. Esto permite cambiar el foco de teclado entre varios ámbitos de foco, pero garantiza que el elemento enfocado dentro del ámbito de foco vuelva a obtener el foco de teclado cuando el foco vuelva al ámbito de foco.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.

Puede haber varios elementos que tengan el foco lógico en una aplicación, pero solo puede haber uno con el foco lógico en un ámbito de foco concreto.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.

Un elemento que tiene el foco de teclado tiene el foco lógico para el ámbito de foco al que pertenece.An element that has keyboard focus has logical focus for the focus scope it belongs to.

Un elemento se puede convertir en un ámbito de foco en Lenguaje XAML (Extensible Application Markup Language)Extensible Application Markup Language (XAML) estableciendo el FocusManager propiedad adjunta IsFocusScope a true.An element can be turned into a focus scope in Lenguaje XAML (Extensible Application Markup Language)Extensible Application Markup Language (XAML) by setting the FocusManager attached property IsFocusScope to true. En el código, se puede convertir un elemento en un ámbito de foco llamando SetIsFocusScope.In code, an element can be turned into a focus scope by calling SetIsFocusScope.

En el ejemplo siguiente se realiza una StackPanel en un ámbito de foco estableciendo el IsFocusScope propiedad adjunta.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 Devuelve el ámbito de foco para el elemento especificado.GetFocusScope returns the focus scope for the specified element.

Las clases de WPFWPF que son ámbitos de foco de forma predeterminada son Window, MenuItem, ToolBar, y ContextMenu.Classes in WPFWPF which are focus scopes by default are Window, MenuItem, ToolBar, and ContextMenu.

GetFocusedElement Obtiene el elemento con foco para el ámbito de foco especificado.GetFocusedElement gets the focused element for the specified focus scope. SetFocusedElement establece el elemento enfocado en el ámbito de foco especificado.SetFocusedElement sets the focused element in the specified focus scope. SetFocusedElement se utiliza normalmente para establecer el elemento con foco inicial.SetFocusedElement is typically used to set the initial focused element.

En el ejemplo siguiente se establece el elemento con foco en un ámbito de foco y se obtiene el elemento con foco de un ámbito de foco.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)

Navegación mediante tecladoKeyboard Navigation

La KeyboardNavigation clase es responsable de implementar la navegación del foco de teclado predeterminada cuando se presiona una de las teclas de navegación.The KeyboardNavigation class is responsible for implementing default keyboard focus navigation when one of the navigation keys is pressed. Las teclas de navegación son: Claves de la ficha, MAYÚS+TAB, CTRL+TAB, CTRL + MAYÚS + TAB, flecha arriba, flecha abajo, izquierda y flecha derecha.The navigation keys are: TAB, SHIFT+TAB, CTRL+TAB, CTRL+SHIFT+TAB, UPARROW, DOWNARROW, LEFTARROW, and RIGHTARROW keys.

Se puede cambiar el comportamiento de navegación de un contenedor de navegación estableciendo el archivo adjunto KeyboardNavigation propiedades TabNavigation, ControlTabNavigation, y DirectionalNavigation.The navigation behavior of a navigation container can be changed by setting the attached KeyboardNavigation properties TabNavigation, ControlTabNavigation, and DirectionalNavigation. Estas propiedades son de tipo KeyboardNavigationMode y los valores posibles son Continue, Local, Contained, Cycle, Once, y None.These properties are of type KeyboardNavigationMode and the possible values are Continue, Local, Contained, Cycle, Once, and None. El valor predeterminado es Continue, lo que significa que el elemento no es un contenedor de navegación.The default value is Continue, which means the element is not a navigation container.

En el ejemplo siguiente se crea un Menu con un número de MenuItem objetos.The following example creates a Menu with a number of MenuItem objects. El TabNavigation se establece la propiedad adjunta en Cycle en el Menu.The TabNavigation attached property is set to Cycle on the Menu. Cuando se cambia el foco mediante la tecla tab dentro de la Menu, el foco se desplazará por cada elemento y cuando se alcanza el último elemento el foco volverá al primer elemento.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 adicional para trabajar con el foco son MoveFocus y PredictFocus.Additional API to work with focus are MoveFocus and PredictFocus.

MoveFocus cambia el foco al siguiente elemento en la aplicación.MoveFocus changes focus to the next element in the application. Un TraversalRequest se usa para especificar la dirección.A TraversalRequest is used to specify the direction. El FocusNavigationDirection pasado a MoveFocus especifica que se puede mover el foco de direcciones diferentes, tales como First, Last, Up y Down.The FocusNavigationDirection passed to MoveFocus specifies the different directions focus can be moved, such as First, Last, Up and Down.

En el ejemplo siguiente se usa MoveFocus para cambiar el elemento con foco.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 Devuelve el objeto que recibiría el foco si fuese a cambiar.PredictFocus returns the object which would receive focus if focus were to be changed. Actualmente, solo Up, Down, Left, y Right son compatibles con PredictFocus.Currently, only Up, Down, Left, and Right are supported by PredictFocus.

Eventos de focoFocus Events

Los eventos relacionados con el foco de teclado son PreviewGotKeyboardFocus, GotKeyboardFocus y PreviewLostKeyboardFocus, LostKeyboardFocus.The events related to keyboard focus are PreviewGotKeyboardFocus, GotKeyboardFocus and PreviewLostKeyboardFocus, LostKeyboardFocus. Los eventos se definen como eventos adjuntos en el Keyboard clase, pero son más fácilmente accesibles como eventos enrutados equivalentes de las clases de elementos base.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. Para obtener más información sobre los eventos, consulte Información general sobre eventos enrutados.For more information about events, see the Routed Events Overview.

GotKeyboardFocus se produce cuando el elemento recibe el foco de teclado.GotKeyboardFocus is raised when the element obtains keyboard focus. LostKeyboardFocus se produce cuando el elemento pierde el foco de teclado.LostKeyboardFocus is raised when the element loses keyboard focus. Si el PreviewGotKeyboardFocus eventos o la PreviewLostKeyboardFocusEvent controla el evento y Handled está establecido en true, a continuación, el foco no cambiará.If the PreviewGotKeyboardFocus event or the PreviewLostKeyboardFocusEvent event is handled and Handled is set to true, then focus will not change.

En el ejemplo siguiente se asocia GotKeyboardFocus y LostKeyboardFocus controladores de eventos a un 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>

Cuando el TextBox recibe el foco de teclado, el Background propiedad de la TextBox cambia a 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

Cuando el TextBox pierde el foco de teclado, el Background propiedad de la TextBox se vuelve a cambiar en blanco.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

Los eventos relacionados con el foco lógico son GotFocus y LostFocus.The events related to logical focus are GotFocus and LostFocus. Estos eventos se definen en el FocusManager como eventos adjuntos, pero el FocusManager no expone contenedores de eventos CLR.These events are defined on the FocusManager as attached events, but the FocusManager does not expose CLR event wrappers. UIElement y ContentElement exponen estos eventos de manera más conveniente.UIElement and ContentElement expose these events more conveniently.

Vea tambiénSee also