Oharra
Baimena behar duzu orria atzitzeko. Direktorioetan saioa has dezakezu edo haiek alda ditzakezu.
Baimena behar duzu orria atzitzeko. Direktorioak alda ditzakezu.
La accesibilidad del teclado debe tratarse como un modelo de interacción principal, no como reserva secundaria. Una sólida experiencia de teclado mejora el soporte para usuarios con diversas discapacidades y limitaciones (incluyendo visuales, de aprendizaje, de destreza/movilidad, y de lenguaje/comunicación). También mejora la productividad de los usuarios que prefieren la interacción con el teclado para la velocidad y la precisión.
Si el acceso al teclado es incompleto o incoherente, los usuarios pueden perder el acceso a la funcionalidad principal de la aplicación incluso cuando la interacción del puntero aparece completamente implementada.
Navegación por teclado entre elementos de la interfaz de usuario
Para interactuar con un control mediante el teclado, los controles deben ser focalizables y alcanzables mediante el recorrido del foco. Para recibir el foco (sin usar un puntero), el control debe ser accesible a través de la navegación mediante tabulador. De forma predeterminada, el orden de tabulación de los controles es el mismo que el orden en que se agregan a una superficie de diseño, se declaran en XAML o se agregan por programación a un contenedor.
En muchas interfaces de usuario, este comportamiento predeterminado es aceptable y se alinea con el flujo de lectura. Sin embargo, el orden visual y el orden del teclado pueden divergir en función del diseño del contenedor y el posicionamiento de los elementos hijos. Esta divergencia debe ser intencionada y probada.
Valide explícitamente el comportamiento de la pestaña. Las cuadrículas, tablas y diseños similares son fuentes comunes de discrepancia entre el orden de lectura percibido y el orden de enfoque. Pruebe las rutas de interacción solo con teclado y táctil para asegurarse de que el recorrido sigue siendo eficaz y predecible.
Para alinear el recorrido con el flujo visual, puedes reestructurar XAML o asignar explícitamente TabIndex. En el siguiente ejemplo se utiliza un Grid con secuencia de tabulación priorizando las columnas.
<Grid>
<Grid.RowDefinitions>...</Grid.RowDefinitions>
<Grid.ColumnDefinitions>...</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" HorizontalAlignment="Center">Groom</TextBlock>
<TextBlock Grid.Column="2" HorizontalAlignment="Center">Bride</TextBlock>
<TextBlock Grid.Row="1">First name</TextBlock>
<TextBox x:Name="GroomFirstName" Grid.Row="1" Grid.Column="1" TabIndex="1"/>
<TextBox x:Name="BrideFirstName" Grid.Row="1" Grid.Column="2" TabIndex="3"/>
<TextBlock Grid.Row="2">Last name</TextBlock>
<TextBox x:Name="GroomLastName" Grid.Row="2" Grid.Column="1" TabIndex="2"/>
<TextBox x:Name="BrideLastName" Grid.Row="2" Grid.Column="2" TabIndex="4"/>
</Grid>
En algunos escenarios, se debe excluir un elemento del recorrido de tabulación. El enfoque estándar es establecer IsEnabled en false, lo que también deshabilita la interacción. Los controles deshabilitados se quitan automáticamente del orden de tabulación.
Si un elemento permanece interactivo a través de otros mecanismos, pero no debe alcanzarse con Tab, establezca IsTabStop en false.
La mayoría de los controles compatibles con foco se incluyen en el orden de tabulación de forma predeterminada. Una excepción común son los controles de visualización de texto, como RichTextBlock, que pueden admitir el enfoque para la selección de texto y las operaciones con el portapapeles, pero normalmente no son paradas de tabulación porque no son controles invocables mediante comandos. Estos controles todavía pueden ser detectados por las tecnologías de asistencia mediante la semántica de automatización, como el patrón de control de texto.
Independientemente de si usa el recorrido predeterminado o tabIndex explícito, se aplican las reglas siguientes:
- Si TabIndex no está establecido en un elemento, el valor predeterminado es Int32.MaxValue y el orden se basa en el orden de declaración o inserción.
- Si TabIndex se establece en un elemento:
El fragmento de código siguiente muestra la configuración de TabIndex mixta (B usa Int32.MaxValue o 2.147.483.647).
<StackPanel Background="#333">
<StackPanel Background="#FF33FF">
<Button>A</Button>
<Button TabIndex="2147483647">B</Button>
<Button>C</Button>
</StackPanel>
<StackPanel Background="#33FFFF">
<Button TabIndex="1">D</Button>
<Button TabIndex="1">E</Button>
<Button TabIndex="0">F</Button>
</StackPanel>
</StackPanel>
Esto genera el siguiente orden de tabulación:
- V
- D
- E
- A
- B
- C
Navegación por el teclado entre paneles de aplicaciones con F6
Un panel de aplicación es una región de tareas destacada dentro de una ventana. En Microsoft Edge, por ejemplo, los paneles incluyen la barra de direcciones, la barra de marcadores, la franja de pestañas y el área de contenido. F6 se usa normalmente para mover el foco entre estos paneles con elementos secundarios accesibles mediante la navegación por teclado estándar.
Aunque un modelo de navegación con teclado compatible es la línea base, un modelo de navegación con teclado utilizable también incluye normalmente:
- Escuchando F6 para moverse entre las principales regiones de la interfaz de usuario.
- Proporcionar métodos abreviados de teclado para comandos de alta frecuencia.
- Proporcionar claves de acceso para controles importantes.
Consulte Métodos abreviados de teclado y teclas de acceso para obtener instrucciones de implementación.
Optimización para F6
F6 reduce significativamente el costo de recorrido al permitir que los usuarios salte entre regiones principales en lugar de desplazarse por cada control secundario.
Por ejemplo, F6 en Microsoft Edge cicla entre la barra de direcciones, la barra de marcadores, la franja de pestañas y el contenido. Dado que una página puede contener muchos tabuladores, esto convierte las tareas de navegación comunes en algo mucho más eficaz.
La secuencia F6 puede alinearse con puntos de referencia o encabezados, pero no es necesario que coincida exactamente. Use F6 para el movimiento general a nivel de región y los puntos de referencia y encabezados para la estructura semántica dentro y entre regiones.
Importante
Debe implementar la navegación F6 explícitamente en la aplicación; no se proporciona automáticamente.
Siempre que sea posible, cada región de destino F6 debe tener un nombre accesible claro, ya sea desde la semántica de punto de referencia o estableciendo AutomationProperties.Name en la raíz de la región.
Mayús+F6 debe recorrer el mismo ciclo en orden inverso.
Navegación por teclado dentro de un elemento de interfaz de usuario
Los controles compuestos deben proporcionar una navegación predecible entre los elementos internos. Un patrón común es mantener la raíz compuesta en el orden de tabulación y administrar los descendientes activos internamente, en lugar de exponer cada hijo como un paso de tabulación independiente.
Muchos controles integrados ya implementan este comportamiento. Por ejemplo, el recorrido de teclas de flecha está disponible de forma predeterminada para ListView, GridView, ListBox y FlipView.
Alternativas de teclado a acciones y eventos de puntero para elementos de control específicos
Cualquier interfaz de usuario que pueda activarse por puntero también debe invocarse mediante el teclado. La activación requiere que el elemento tenga el foco (solo las clases que derivan de Control admiten el foco y la navegación por tabulación).
Para los controles que se pueden invocar, implemente controladores de eventos de teclado para la barra espaciadora y las teclas Entrar. Esto proporciona paridad básica del teclado con interacciones de puntero.
Si un elemento no es compatible con el foco de forma predeterminada, use un tipo de control enfocado o implemente un control personalizado con un comportamiento explícito del foco. En ese caso, establezca IsTabStop en true y proporcione un indicador de foco visible.
En muchos casos, la composición es más sencilla y robusta que un comportamiento personalizado basado exclusivamente en punteros. Por ejemplo, en lugar de controlar la entrada del puntero directamente en una imagen, colóquela dentro de un botón para heredar la activación del teclado, el control de foco y el comportamiento de automatización.
<!--Don't do this.-->
<Image Source="sample.jpg" PointerPressed="Image_PointerPressed"/>
<!--Do this instead.-->
<Button Click="Button_Click"
AutomationProperties.Name="Open profile photo">
<Image Source="Assets/profile-photo.png"/>
</Button>
Accesos directos del teclado
Además de la navegación y la activación, implemente un acceso directo (una combinación de teclas que proporciona acceso eficaz a la funcionalidad de la aplicación) para comandos importantes o usados con frecuencia con aceleradores de teclado y teclas de acceso.
Dos tipos comunes de acceso directo son:
- Aceleradores: invoque comandos directamente, con o sin un control visible correspondiente.
- Claves de acceso: mueva el foco a controles específicos de la interfaz de usuario.
Haga que los accesos directos siempre sean reconocibles para los usuarios de la tecnología de asistencia. Comunicarlos a través de información sobre herramientas, metadatos de automatización, prestaciones visibles de la interfaz de usuario y documentación de ayuda.
Para exponer metadatos de acceso directo a tecnologías de asistencia, use AutomationProperties.AccessKey para accesos directos mnemónicos y AutomationProperties.AcceleratorKey para los métodos abreviados de comandos. Dado que los lectores de pantalla pueden presentar de forma similar estos accesos directos, documente los accesos directos de documentos en varios canales.
En el ejemplo siguiente se muestra cómo documentar las teclas de método abreviado para los botones de reproducción, pausa y detención multimedia.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<MediaPlayerElement x:Name="DemoPlayer"
Width="500" Height="300" Margin="20"
HorizontalAlignment="Center"
AutoPlay="False"
AreTransportControlsEnabled="True" />
<StackPanel Grid.Row="1" Margin="10"
Orientation="Horizontal" HorizontalAlignment="Center">
<Button x:Name="PlayButton" Click="MediaButton_Click"
ToolTipService.ToolTip="Shortcut key: Ctrl+P"
AutomationProperties.AcceleratorKey="Ctrl+P"
AutomationProperties.AccessKey="Alt+P">
<Button.KeyboardAccelerators>
<KeyboardAccelerator Modifiers="Control" Key="P"/>
</Button.KeyboardAccelerators>
<TextBlock>Play</TextBlock>
</Button>
<Button x:Name="PauseButton" Click="MediaButton_Click"
ToolTipService.ToolTip="Shortcut key: Ctrl+A"
AutomationProperties.AcceleratorKey="Ctrl+A"
AutomationProperties.AccessKey="Alt+A">
<Button.KeyboardAccelerators>
<KeyboardAccelerator Modifiers="Control" Key="A"/>
</Button.KeyboardAccelerators>
<TextBlock>Pause</TextBlock>
</Button>
<Button x:Name="StopButton" Click="MediaButton_Click"
ToolTipService.ToolTip="Shortcut key: Ctrl+S"
AutomationProperties.AcceleratorKey="Ctrl+S"
AutomationProperties.AccessKey="Alt+S">
<Button.KeyboardAccelerators>
<KeyboardAccelerator Modifiers="Control" Key="S"/>
</Button.KeyboardAccelerators>
<TextBlock>Stop</TextBlock>
</Button>
</StackPanel>
</Grid>
Importante
Establecer AutomationProperties.AcceleratorKey o AutomationProperties.AccessKey no implementa el comportamiento del teclado. Estas propiedades exponen metadatos a la automatización de la interfaz de usuario para que las tecnologías de asistencia puedan anunciar los accesos directos esperados.
El comportamiento del teclado todavía debe implementarse en el código. Use definiciones declarativas keyboardAccelerator siempre que sea posible y use los controladores KeyDown o KeyUp en los que necesite lógica de enrutamiento personalizada. Tenga en cuenta también que el subrayado de las teclas de acceso rápido no es automático. Si desea subrayados mnemónicos visibles, muéstrelos explícitamente (por ejemplo, con Subrayado).
Por motivos de brevedad, el ejemplo omite los recursos de cadena como "Ctrl+A". En producción, localice el texto de atajos y valide las combinaciones mnemónicas según la localización, ya que la selección de teclas a menudo depende de las etiquetas traducidas.
Para obtener instrucciones adicionales, consulte Teclas de método abreviado en las Directrices de interacción de la experiencia del usuario de Windows.
Implementación de un controlador de eventos clave
La entrada de clave usa eventos enrutados. Los eventos enrutados pueden propagarse desde elementos secundarios a un contenedor padre, lo que permite al contenedor padre procesar accesos directos para múltiples elementos descendientes. Este modelo de eventos es cómodo para definir acciones de teclas de acceso rápido para un control que contiene varios elementos secundarios, y ninguno de ellos puede recibir el foco ni formar parte de la secuencia de tabulación.
Para ver ejemplos de código que incluyen comprobaciones de teclas modificadores (por ejemplo, Ctrl), vea Interacciones del teclado.
Navegación por teclado para controles personalizados
Para los controles personalizados, use las teclas de dirección cuando los elementos secundarios estén relacionados espacialmente. En escenarios de árbol en los que expandir/contraer y la activación son interacciones independientes, asigna las flechas izquierda y derecha a la función de expandir/contraer. Para los controles orientados, asigne teclas direccionales a la orientación visual del control.
El comportamiento de clave personalizada se implementa normalmente reemplazando OnKeyDown y OnKeyUp.
Ejemplo de un estado visual para un indicador de foco
Cualquier control personalizado enfocable debe exponer un indicador visual de enfoque claro. Un patrón de plantilla común usa una superposición rectángulo que comienza oculta a través de Visibilidad y aparece cuando entra el foco.
Los controles XAML integrados ya proporcionan indicadores de foco. La apariencia exacta puede variar con la configuración del tema, incluido el modo de contraste alto. Si vuelve a rediseñar las plantillas de los controles, conserve el comportamiento equivalente de visibilidad del enfoque.
En el ejemplo siguiente se adapta a partir de la plantilla Botón predeterminada.
<ControlTemplate TargetType="Button">
...
<Rectangle
x:Name="FocusVisualWhite"
IsHitTestVisible="False"
Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="1.5"/>
<Rectangle
x:Name="FocusVisualBlack"
IsHitTestVisible="False"
Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="0.5"/>
...
</ControlTemplate>
Para alternar la visibilidad del indicador de foco, use VisualStateManager y VisualStateManager.VisualStateGroups en la raíz de la plantilla.
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<!--other visual state groups here-->
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="FocusVisualWhite"
Storyboard.TargetProperty="Opacity"
To="1" Duration="0"/>
<DoubleAnimation
Storyboard.TargetName="FocusVisualBlack"
Storyboard.TargetProperty="Opacity"
To="1" Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!--composition is here-->
</Grid>
</ControlTemplate>
Solo un estado de este grupo modifica explícitamente el enfoque visual. Los demás estados pueden permanecer vacíos porque las transiciones dentro de la misma visualStateGroup cancelan las animaciones de estado anteriores. Los eventos de enfoque como GotFocus, combinados con GoToState, normalmente impulsan estas transiciones.
Accesibilidad del teclado y dispositivos sin un teclado de hardware
Algunos dispositivos dependen de un Panel de Entrada Suave (SIP) en lugar de un teclado de hardware. Los lectores de pantalla pueden detectar que el usuario está examinando las teclas y anunciar la exploración de teclas SIP de un usuario, y muchos conceptos de accesibilidad del teclado se siguen aplicando a través de equivalentes de gestos.
Por ejemplo, incluso sin una tecla física de Tab, Narrator admite gestos que se asignan a un recorrido similar al de Tab. Esto significa que el orden de tabulación coherente sigue siendo crítico. Narrador también proporciona equivalentes de gestos para la navegación direccional en controles complejos (consulte Comandos de teclado narrador y gestos táctiles).
Ejemplos
![]()
La aplicación Galería de WinUI 3 incluye ejemplos interactivos de características y controles winUI. Obtenga la aplicación del Microsoft Store o examine el código fuente en GitHub.
Temas relacionados
- Información general sobre accesibilidad
- Interacciones de teclado
- Ejemplo de teclado táctil (ejemplo heredado)
- Ejemplo de accesibilidad XAML (ejemplo heredado archivado)
Windows developer