Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Usa la navegación de foco para proporcionar experiencias de interacción completas y coherentes en tus aplicaciones de Windows y controles personalizados para los usuarios avanzados del teclado, aquellos con discapacidades y otros requisitos de accesibilidad, así como la experiencia de 10 pies de pantallas de televisión y Xbox One.
Información general
La navegación de foco hace referencia al mecanismo subyacente que permite a los usuarios navegar e interactuar con la interfaz de usuario de una aplicación de Windows mediante un teclado, un controlador para juegos o un control remoto.
Nota:
Normalmente, los dispositivos de entrada se clasifican como dispositivos apuntadores, como táctil, touchpad, lápiz y ratón, y dispositivos no apuntadores, como teclado, mando de juego y mando a distancia.
En este tema se describe cómo optimizar una aplicación de Windows y crear experiencias de interacción personalizadas para los usuarios que dependen de tipos de entrada no apuntados.
Aunque nos centramos en la entrada de teclado para controles personalizados en aplicaciones de Windows en equipos, una experiencia de teclado bien diseñada también es importante para teclados de software, como el teclado táctil y el teclado en pantalla (OSK), que soportan herramientas de accesibilidad como Narrador de Windows y la experiencia a 10 pies de distancia.
Consulte Handle pointer input (Controlar la entrada del puntero) para obtener instrucciones sobre cómo crear experiencias personalizadas en aplicaciones de Windows para dispositivos señaladores.
Para obtener más información general sobre la creación de aplicaciones y experiencias para el teclado, consulte Interacción con el teclado.
Guía general
Solo los elementos de la interfaz de usuario que requieren interacción del usuario deben admitir la navegación de foco, los elementos que no requieren una acción, como imágenes estáticas, no necesitan el foco del teclado. Los lectores de pantalla y las herramientas de accesibilidad similares siguen anunciando estos elementos estáticos, incluso cuando no se incluyen en la navegación de foco.
Es importante recordar que, a diferencia de navegar con un dispositivo de puntero, como un mouse o un toque, la navegación de foco es lineal. Al implementar la navegación de foco, considere cómo interactuará un usuario con la aplicación y cuál debe ser la navegación lógica. En la mayoría de los casos, se recomienda que el comportamiento personalizado de navegación de foco siga el patrón de lectura preferido por la cultura del usuario.
Algunos otros aspectos a considerar en la navegación por foco incluyen:
- ¿Los controles se agrupan lógicamente?
- ¿Hay grupos de controles con mayor importancia?
- Si es así, ¿esos grupos contienen subgrupos?
- ¿El diseño requiere navegación direccional personalizada (teclas de dirección) y orden de tabulación?
El libro electrónico Engineering Software for Accessibility tiene un excelente capítulo sobre diseño de la jerarquía lógica.
Navegación direccional 2D para el teclado
La región de navegación interna 2D de un control o grupo de controles se conoce como su "área direccional". Cuando el foco cambia a este objeto, las teclas de dirección del teclado (izquierda, derecha, arriba y abajo) se pueden usar para navegar entre los elementos secundarios dentro del área direccional.
Región de navegación interna 2D, o área direccional, de un grupo de control
Puede usar la propiedad XYFocusKeyboardNavigation (que tiene valores posibles de Auto, Enabled o Disabled) para administrar la navegación interna 2D con las teclas de dirección del teclado.
Nota:
El orden de tabulación no se ve afectado por esta propiedad. Para evitar una experiencia de navegación confusa, se recomienda que los elementos hijos de un área direccional no se especifiquen explícitamente en el orden de tabulación de su aplicación. Consulte las propiedades UIElement.TabFocusNavigation y TabIndex para obtener más detalles sobre el comportamiento de tabulación de un elemento.
Automático (comportamiento predeterminado)
Cuando se establece en Automático, el comportamiento de navegación direccional viene determinado por la herencia o la jerarquía de herencia del elemento. Si todos los antecesores están en modo predeterminado (establecido en Automático), no se admite la navegación direccional con el teclado.
Deshabilitado
Establezca XYFocusKeyboardNavigation en Disabled para bloquear la navegación direccional al control y sus elementos secundarios.
Comportamiento deshabilitado de XYFocusKeyboardNavigation
En este ejemplo, el StackPanel principal (ContainerPrimary) tiene XYFocusKeyboardNavigation establecido en Habilitado. Todos los elementos secundarios heredan esta configuración y se puede navegar a ellos con las teclas de flecha. Sin embargo, los elementos B3 y B4 están en un StackPanel secundario (ContainerSecondary) con XYFocusKeyboardNavigation establecido en Disabled, lo que anula el contenedor principal y desactiva la navegación mediante las teclas de flecha hacia él mismo y entre sus elementos secundarios.
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="75"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Name="ContainerPrimary"
XYFocusKeyboardNavigation="Enabled"
KeyDown="ContainerPrimary_KeyDown"
Orientation="Horizontal"
BorderBrush="Green"
BorderThickness="2"
Grid.Row="1"
Padding="10"
MaxWidth="200">
<Button Name="B1"
Content="B1"
GettingFocus="Btn_GettingFocus" />
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus" />
<StackPanel Name="ContainerSecondary"
XYFocusKeyboardNavigation="Disabled"
Orientation="Horizontal"
BorderBrush="Red"
BorderThickness="2">
<Button Name="B3"
Content="B3"
GettingFocus="Btn_GettingFocus" />
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus" />
</StackPanel>
</StackPanel>
</Grid>
Enabled
Establezca XYFocusKeyboardNavigation en Habilitado para admitir la navegación direccional 2D en un control y cada uno de sus objetos secundarios UIElement .
Cuando se establece, la navegación con las teclas de dirección está restringida a elementos dentro del área direccional. La navegación por tabulación no se ve afectada, ya que todos los controles permanecen accesibles a través de su jerarquía de orden de tabulación.
Comportamiento de XYFocusKeyboardNavigation habilitado
En este ejemplo, el StackPanel principal (ContainerPrimary) tiene XYFocusKeyboardNavigation establecido en Habilitado. Todos los elementos secundarios heredan esta configuración y se puede navegar con las teclas de dirección. Los elementos B3 y B4 están en un stackPanel secundario (ContainerSecondary) donde XYFocusKeyboardNavigation no está establecido, lo que hereda la configuración del contenedor principal. El elemento B5 no está dentro de un área direccional declarada y no admite la navegación por teclas de flecha, pero sí admite el comportamiento de navegación por tabulación estándar.
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Grid.Row="1"
Orientation="Horizontal"
HorizontalAlignment="Center">
<StackPanel Name="ContainerPrimary"
XYFocusKeyboardNavigation="Enabled"
KeyDown="ContainerPrimary_KeyDown"
Orientation="Horizontal"
BorderBrush="Green"
BorderThickness="2"
Padding="5" Margin="5">
<Button Name="B1"
Content="B1"
GettingFocus="Btn_GettingFocus" Margin="5" />
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus" />
<StackPanel Name="ContainerSecondary"
Orientation="Horizontal"
BorderBrush="Red"
BorderThickness="2"
Margin="5">
<Button Name="B3"
Content="B3"
GettingFocus="Btn_GettingFocus"
Margin="5" />
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus"
Margin="5" />
</StackPanel>
</StackPanel>
<Button Name="B5"
Content="B5"
GettingFocus="Btn_GettingFocus"
Margin="5" />
</StackPanel>
</Grid>
Puede tener varios niveles de áreas direccionales anidadas. Si todos los elementos primarios tienen XYFocusKeyboardNavigation establecido en Habilitado, se omiten los límites de la región de navegación interna.
Este es un ejemplo de dos áreas direccionales anidadas dentro de un elemento que no admite explícitamente la navegación direccional 2D. En este caso, no se admite la navegación direccional entre las dos áreas anidadas.
XYFocusKeyboardNavigation habilitado y comportamiento anidado
Este es un ejemplo más complejo de tres áreas direccionales anidadas donde:
- Cuando B1 tiene el foco, solo se puede navegar a B5 (y viceversa) porque hay un límite de área direccional en el que XYFocusKeyboardNavigation está configurado como deshabilitado, lo que hace que B2, B3 y B4 no se puedan acceder con las teclas de dirección.
- Cuando B2 tiene el foco, solo se puede navegar a B3 (y viceversa) porque el límite del área direccional impide la navegación con las teclas de dirección a B1, B4 y B5.
- Cuando B4 tiene el foco, se debe usar la tecla Tab para navegar entre los controles.
Comportamiento anidado complejo y habilitado de XYFocusKeyboardNavigation
Navegación por tabulación
Aunque las teclas de dirección se pueden usar para la navegación direccional en 2D dentro de un control o un grupo de controles, se puede usar la tecla Tabulador para navegar entre todos los controles de una aplicación de Windows.
Todos los controles interactivos admiten la navegación por teclas tab de forma predeterminada (la propiedad IsEnabled e IsTabStop son true), con el orden de tabulación lógico derivado del diseño de control en la aplicación. Sin embargo, el orden predeterminado no corresponde necesariamente al orden visual. La posición de visualización real puede depender del contenedor de diseño primario y de determinadas propiedades que puede establecer en los elementos secundarios para influir en el diseño.
Evite un orden de tabulación personalizado que haga que el foco salte por la aplicación. Por ejemplo, una lista de controles de un formulario debe tener un orden de tabulación que fluya de arriba a abajo y de izquierda a derecha (según la configuración regional).
En esta sección se describe cómo este orden de tabulación se puede personalizar completamente para adaptarse a la aplicación.
Establecimiento del comportamiento de navegación de pestañas
La propiedad TabFocusNavigation de UIElement especifica el comportamiento de navegación de tabulación para todo su árbol de objetos (o área direccional).
Nota:
Utilice esta propiedad en lugar de la propiedad Control.TabNavigation para los objetos que no usan controlTemplate para definir su apariencia.
Como hemos mencionado en la sección anterior, para evitar una experiencia de navegación confusa, se recomienda que los elementos secundarios de un área direccional no se especifiquen explícitamente en el orden de navegación por pestañas de la aplicación. Consulte las propiedades UIElement.TabFocusNavigation y TabIndex para obtener más detalles sobre el comportamiento de tabulación de un elemento.
Para versiones anteriores a Windows 10 Creators Update (compilación 10.0.15063), la configuración de pestañas se limitaba a objetos ControlTemplate . Para obtener más información, consulta Control.TabNavigation.
TabFocusNavigation tiene un valor de tipo KeyboardNavigationMode con los siguientes valores posibles (tenga en cuenta que estos ejemplos no son grupos de controles personalizados y no requieren navegación interna con las teclas de dirección):
Local (predeterminado) Los índices de tabulación se reconocen en el subárbol local dentro del contenedor. En este ejemplo, el orden de tabulación es B1, B2, B3, B4, B5, B6, B7, B1.
Comportamiento de navegación de pestañas "Local"
Una vez El contenedor y todos los elementos secundarios reciben el foco una vez. En este ejemplo, el orden de tabulación es B1, B2, B7, B1 (también se muestra la navegación interna con la tecla de flecha).
Comportamiento de navegación de pestañas "Una vez"
Cycle
El foco vuelve al elemento centrado inicial dentro de un contenedor. En este ejemplo, el orden de tabulación es B1, B2, B3, B4, B5, B6, B2...
Comportamiento de navegación por pestañas "Ciclo"
Este es el código de los ejemplos anteriores (con TabFocusNavigation ="Cycle").
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="300"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Name="ContainerPrimary"
KeyDown="Container_KeyDown"
Orientation="Horizontal"
HorizontalAlignment="Center"
BorderBrush="Green"
BorderThickness="2"
Grid.Row="1"
Padding="10"
MaxWidth="200">
<Button Name="B1"
Content="B1"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<StackPanel Name="ContainerSecondary"
KeyDown="Container_KeyDown"
XYFocusKeyboardNavigation="Enabled"
TabFocusNavigation ="Cycle"
Orientation="Vertical"
VerticalAlignment="Center"
BorderBrush="Red"
BorderThickness="2"
Padding="5" Margin="5">
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B3"
Content="B3"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B5"
Content="B5"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B6"
Content="B6"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
<Button Name="B7"
Content="B7"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
</Grid>
TabIndex
Use TabIndex para especificar el orden en el que los elementos reciben el foco cuando el usuario navega por los controles mediante la tecla Tab. Un control con un índice de tabulación inferior recibe el foco antes de un control con un índice superior.
Cuando un control no tiene especificado TabIndex , se le asigna un valor de índice mayor que el valor de índice más alto actual (y la prioridad más baja) de todos los controles interactivos del árbol visual, en función del ámbito.
Todos los elementos secundarios de un control se consideran un ámbito y, si uno de estos elementos también tiene elementos secundarios, se consideran otro ámbito. Cualquier ambigüedad se resuelve eligiendo el primer elemento en el árbol visual del ámbito.
Para excluir un control del orden de tabulación, establezca la propiedad IsTabStop en false.
Invalide el orden de tabulación predeterminado estableciendo la propiedad TabIndex .
Nota:
TabIndex funciona de la misma manera con UIElement.TabFocusNavigation y Control.TabNavigation.
Aquí se muestra cómo la navegación de foco puede verse afectada por la propiedad TabIndex en elementos específicos.
Navegación en la pestaña "Local" con el comportamiento de TabIndex
En el ejemplo anterior, hay dos ámbitos:
- B1, área direccional (B2 - B6) y B7
- área direccional (B2 - B6)
Cuando B3 (en el área direccional) obtiene el foco, el ámbito cambia y la navegación por tabulación se transfiere al área direccional donde se identifica el mejor candidato para el foco posterior. En este caso, B2 seguido de B4, B5 y B6. El ámbito vuelve a cambiar y el foco se mueve a B1.
Este es el código de este ejemplo.
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
TabFocusNavigation="Cycle">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="300"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="KeyPressed"
Grid.Row="0"
FontWeight="ExtraBold"
HorizontalTextAlignment="Center"
TextWrapping="Wrap"
Padding="10" />
<StackPanel Name="ContainerPrimary"
KeyDown="Container_KeyDown"
Orientation="Horizontal"
HorizontalAlignment="Center"
BorderBrush="Green"
BorderThickness="2"
Grid.Row="1"
Padding="10"
MaxWidth="200">
<Button Name="B1"
Content="B1"
TabIndex="1"
ToolTipService.ToolTip="TabIndex = 1"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<StackPanel Name="ContainerSecondary"
KeyDown="Container_KeyDown"
TabFocusNavigation ="Local"
Orientation="Vertical"
VerticalAlignment="Center"
BorderBrush="Red"
BorderThickness="2"
Padding="5" Margin="5">
<Button Name="B2"
Content="B2"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B3"
Content="B3"
TabIndex="3"
ToolTipService.ToolTip="TabIndex = 3"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B4"
Content="B4"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B5"
Content="B5"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
<Button Name="B6"
Content="B6"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
<Button Name="B7"
Content="B7"
TabIndex="2"
ToolTipService.ToolTip="TabIndex = 2"
GettingFocus="Btn_GettingFocus"
Margin="5"/>
</StackPanel>
</Grid>
Navegación direccional 2D para teclado, controlador para juegos y control remoto
Los tipos de entrada que no son de puntero, como teclado, controlador para juegos, control remoto y herramientas de accesibilidad como Narrador de Windows, comparten un mecanismo común subyacente para navegar e interactuar con la interfaz de usuario de la aplicación Windows.
En esta sección, tratamos cómo especificar una estrategia de navegación preferida y afinar la navegación enfocada dentro de tu aplicación a través de un conjunto de propiedades de estrategia de navegación que admiten todos los tipos de entrada no basados en puntero y centrados en el foco.
Para obtener más información general sobre la creación de aplicaciones y experiencias para Xbox/TV, consulta Interacción del teclado, Diseño para Xbox y TV, y Controlador para juegos y interacciones de control remoto.
Estrategias de navegación
Las estrategias de navegación son aplicables al teclado, el controlador para juegos, el control remoto y varias herramientas de accesibilidad.
Las siguientes propiedades de estrategia de navegación permiten influir en qué control recibe el foco en función de la tecla de flecha, el botón del panel direccional (D-pad) u otro botón similar presionado.
- XYFocusUpNavigationStrategy (Estrategia de Navegación hacia Arriba con Enfoque XY)
- EstrategiaDeNavegaciónHaciaAbajoConEnfoqueXY
- XYFocusLeftNavigationStrategy
- XYFocusRightNavigationStrategy
Estas propiedades tienen valores posibles de Auto (valor predeterminado), NavigationDirectionDistance, Projection o RectilinearDistance .
Si se establece en Auto, el comportamiento del elemento se basa en los antecesores del elemento. Si todos los elementos se establecen en Auto, se usa Proyección .
Nota:
Otros factores, como el elemento centrado anteriormente o la proximidad al eje de la dirección de navegación, pueden influir en el resultado.
Projection
La estrategia de proyección mueve el foco al primer elemento encontrado cuando se proyecta el borde del elemento centrado actualmente en la dirección de la navegación.
En este ejemplo, cada dirección de navegación del foco se establece en Proyección. Observe cómo el foco se mueve de B1 a B4, saltándose B3. Esto se debe a que B3 no está en la zona de proyección. Observe también cómo no se identifica un candidato de enfoque al desplazarse hacia la izquierda desde B1. Esto se debe a que la posición de B2 relativa a B1 elimina B3 como candidato. Si B3 estuviera en la misma fila que B2, sería un candidato viable para la navegación izquierda. B2 es un candidato viable debido a su proximidad sin obstáculos al eje de la dirección de navegación.
Estrategia de navegación por proyección
DistanciaDeDirecciónDeNavegación
La estrategia NavigationDirectionDistance mueve el foco al elemento más cercano al eje de la dirección de navegación.
El borde del rectángulo delimitador correspondiente a la dirección de navegación se extiende y se proyecta para identificar los destinos candidatos. El primer elemento encontrado se designa como objetivo. En el caso de varios candidatos, el elemento más cercano se identifica como el objetivo. Si todavía hay varios candidatos, el elemento más superior o izquierdo se identifica como el candidato.
NavigationDirectionDistance navigation strategy (Estrategia de navegación de NavigationDirectionDistance)
Distancia rectilínea
La estrategia RectilinearDistance mueve el enfoque al elemento más cercano según la distancia bidimensional rectilineal (geometría de Taxicab).
La suma de la distancia primaria y la distancia secundaria a cada candidato potencial se usa para identificar el mejor candidato. En un empate, se selecciona el primer elemento a la izquierda si la dirección solicitada está hacia arriba o hacia abajo y se selecciona el primer elemento a la parte superior si la dirección solicitada es izquierda o derecha.
Estrategia de navegación de distancia rectilínea
En esta imagen se muestra cómo, cuando B1 tiene el foco y la dirección hacia abajo es la dirección solicitada, B3 es el candidato de enfoque RectilinearDistance. Esto se basa en las siguientes calcualizaciones para este ejemplo:
- Distancia (B1, B3, Abajo) es igual a 10 + 0 = 10
- Distancia (B1, B2, Abajo) es 0 + 40 = 30
- Distancia (B1, D, Abajo) es 30 + 0 = 30