Compartir vía


Accesibilidad de teclado

Crear accesibilidad de teclado (para hardware tradicional, modificado o emulación de teclado) en la aplicación, proporciona a los usuarios ciegos, tienen poca visión, discapacidades motoras o tienen poco o ningún uso de sus manos, la capacidad de navegar por y usar la funcionalidad completa de la aplicación. Además, los usuarios sin discapacidades pueden elegir el teclado para la navegación debido a la preferencia o la eficacia.

Si la aplicación no proporciona un buen acceso al teclado, es posible que los usuarios ciegos o que tengan problemas de movilidad puedan tener dificultades para usar la aplicación.

Navegación por teclado entre elementos de la interfaz de usuario

Para interactuar con un control mediante el teclado, el control debe tener el foco. Para recibir el foco (sin usar un puntero), el control debe ser accesible a través de la navegación por tabulación. De forma predeterminada, el orden de tabulación de los controles es el mismo que el orden en el que se agregan a una superficie de diseño, se declara en XAML o se agrega mediante programación a un contenedor.

Normalmente, el orden de tabulación predeterminado se basa en cómo se definen los controles en XAML, especialmente cuando es el orden en que los lectores de pantalla atraviesan los controles. 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 varias propiedades de elementos secundarios que pueden afectar al diseño.

Para asegurarse de que la aplicación tiene un orden de tabulación óptimo, pruebe el comportamiento usted mismo. Si usa una cuadrícula o tabla para el diseño, el orden en el que los usuarios podrían leer la pantalla frente al orden de tabulación podría ser muy diferente. Esto no siempre es un problema, pero solo asegúrate de probar la funcionalidad de la aplicación a través de la entrada táctil y el teclado para comprobar que la interfaz de usuario está optimizada para ambos métodos de entrada.

Puedes hacer que el orden de tabulación coincida con el orden visual ajustando el XAML o reemplazando el orden de tabulación predeterminado. En el ejemplo siguiente se muestra cómo usar la propiedad TabIndex con un diseño grid que usa la navegación por tabulación de 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 casos, es posible que desee excluir un control específico del orden de tabulación. Esto se logra normalmente haciendo que el control no interactive estableciendo su propiedad IsEnabled en false. Un control deshabilitado se excluye automáticamente del orden de tabulación.

Si desea excluir un control interactivo del orden de tabulación, puede establecer la propiedad IsTabStop en false.

De forma predeterminada, los elementos de la interfaz de usuario que admiten el foco se incluyen normalmente en el orden de tabulación. Algunas excepciones a esto incluyen determinados tipos de visualización de texto (como RichTextBlock) que admiten el foco para la selección de texto y el acceso al Portapapeles, pero no están en el orden de tabulación porque son elementos de texto estáticos. Estos controles no son convencionalesmente interactivos (no se pueden invocar y no requieren entrada de texto, pero admiten el patrón de control Texto que admite la búsqueda y ajuste de puntos de selección en texto). Las tecnologías de asistencia seguirán detectando controles de texto y leen en voz alta en los lectores de pantalla, pero que se basan en técnicas distintas del orden de tabulación.

Tanto si ajusta los valores de TabIndex como si usa el orden predeterminado, se aplican estas reglas:

  • Si TabIndex no está establecido en un elemento, el valor predeterminado es Int32.MaxValue y el orden de tabulación se basa en el orden de declaración en las colecciones XAML o secundarias.
  • Si TabIndex se establece en un elemento:
    • Los elementos de la interfaz de usuario con TabIndex igual a 0 se agregan al orden de tabulación en función del orden de declaración en colecciones XAML o secundarias.
    • Los elementos de la interfaz de usuario con TabIndex mayores que 0 se agregan al orden de tabulación en función del valor tabIndex.
    • Los elementos de la interfaz de usuario con TabIndex menor que 0 se agregan al orden de tabulación y aparecen antes de cualquier valor cero.

En el fragmento de código siguiente se muestra una colección de elementos con varios valores de TabIndex (B se le asigna el valor de 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 da como resultado el siguiente orden de tabulación:

  1. F
  2. D
  3. E
  4. A
  5. B
  6. C

Navegación por el teclado entre paneles de aplicaciones con F6

Un panel de aplicación es un área lógica de una interfaz de usuario destacada relacionada dentro de una ventana de aplicación (por ejemplo, los paneles de Microsoft Edge incluyen la barra de direcciones, la barra de marcadores, la barra de pestañas y el panel de contenido). La tecla F6 se puede usar para navegar entre estos paneles, donde se puede acceder a grupos de elementos secundarios mediante la navegación por teclado estándar.

Aunque la navegación por el teclado puede proporcionar una interfaz de usuario compatible con el acceso, la realización de una interfaz de usuario accesible a menudo requiere algunos pasos más. Normalmente, esto incluye:

  • Escuchando F6 para navegar entre secciones importantes de la interfaz de usuario.
  • Agregar métodos abreviados de teclado para acciones comunes en la interfaz de usuario.
  • Agregar claves de acceso a controles importantes en la interfaz de usuario.

Consulte Métodos abreviados de teclado a continuación y Teclas de acceso para obtener más instrucciones sobre cómo implementar métodos abreviados y teclas de acceso.

Optimización para F6

F6 permite a los usuarios del teclado navegar eficazmente entre paneles de la interfaz de usuario sin tabular a través de potencialmente cientos de controles.

Por ejemplo, F6 en Microsoft Edge ciclos entre la barra de direcciones, la barra de marcadores, la barra de pestañas y el panel de contenido. Como una página web puede tener cientos de controles tabulables, F6 puede facilitar que los usuarios del teclado lleguen a la barra de pestañas y la barra de direcciones sin usar accesos directos específicos de la aplicación.

El ciclo de tabulación F6 también puede corresponder de forma flexible a puntos de referencia o encabezados en el contenido, aunque no es necesario que coincida exactamente. F6 debe centrarse en regiones grandes y distintas de la interfaz de usuario, mientras que los puntos de referencia pueden ser más granulares. Por ejemplo, puede marcar una barra de aplicaciones y su cuadro de búsqueda como puntos de referencia, pero solo incluir la propia barra de aplicaciones en el ciclo F6.

Importante

Debes implementar la navegación F6 en la aplicación, ya que no se admite de forma nativa.

Siempre que sea posible, las regiones del ciclo F6 deben tener un nombre accesible: a través de un punto de referencia o agregando manualmente un AutomationProperties.Name al elemento "raíz" de la región.

Shift-F6 debe desplazarse en la dirección opuesta.

Navegación por teclado dentro de un elemento de interfaz de usuario

Para los controles compuestos, es importante garantizar una navegación interna adecuada entre los elementos contenidos. Un control compuesto puede administrar el elemento secundario activo actualmente para reducir la sobrecarga de que todos los elementos secundarios admitan el foco. El control compuesto se incluye en el orden de tabulación y controla los eventos de navegación del teclado. Muchos controles compuestos ya tienen alguna lógica de navegación interna integrada en su control de eventos. Por ejemplo, el recorrido de teclas de flecha de los elementos está habilitado de forma predeterminada en los controles ListView, GridView, ListBox y FlipView.

Alternativas de teclado a acciones y eventos de puntero para elementos de control específicos

Los elementos de la interfaz de usuario que se pueden hacer clic también deben invocarse a través del teclado. Para usar el teclado con un elemento de interfaz de usuario, el elemento debe tener el foco (solo las clases que derivan del control admiten el foco y la navegación de tabulación).

Para los elementos de la interfaz de usuario que se pueden invocar, implemente controladores de eventos de teclado para la barra espaciadora y las teclas Entrar. Esto garantiza la compatibilidad básica con la accesibilidad del teclado y permite a los usuarios llegar a todos los elementos interactivos de la interfaz de usuario y activar la funcionalidad solo con el teclado.

Cuando un elemento no admite el foco, puede crear su propio control personalizado. En este caso, para habilitar el foco, debe establecer la propiedad IsTabStop en true y debe proporcionar una indicación visual del estado visual centrado con un indicador de foco.

Sin embargo, puede ser más fácil usar la composición del control para que la compatibilidad con tabulaciones, el foco y los patrones del mismo nivel y los patrones de Microsoft Automatización de la interfaz de usuario se controlen mediante el control en el que se elige componer el contenido. Por ejemplo, en lugar de controlar un evento presionado por puntero en una imagen, ajuste ese elemento en un botón para obtener el puntero, el teclado y la compatibilidad con el foco.

<!--Don't do this.-->
<Image Source="sample.jpg" PointerPressed="Image_PointerPressed"/>

<!--Do this instead.-->
<Button Click="Button_Click"><Image Source="sample.jpg"/></Button>

Accesos directos del teclado

Además de implementar la navegación y activación del teclado, también se recomienda implementar métodos abreviados de teclado, como aceleradores de teclado y teclas de acceso para funcionalidades importantes o usadas con frecuencia.

Un método abreviado es una combinación de teclado que proporciona una manera eficaz de que el usuario acceda a la funcionalidad de la aplicación. Existen dos tipos de vistas:

  • Los aceleradores son accesos directos que invocan un comando de aplicación. Es posible que la aplicación proporcione o no una interfaz de usuario específica que corresponda al comando. Normalmente, los aceleradores constan de la tecla Ctrl más una tecla de letra.
  • Las secuencia de teclas son métodos abreviados que establecen el foco en una interfaz de usuario específica de la aplicación. Las claves de acceso típicas constan de la tecla Alt más una tecla de letra.

Proporcionar siempre una manera fácil para los usuarios que dependen de lectores de pantalla y otra tecnología de asistencia para detectar las teclas de método abreviado de la aplicación. Comunique las teclas de método abreviado mediante información sobre herramientas, nombres accesibles, descripciones accesibles o alguna otra forma de comunicación en pantalla. Como mínimo, las teclas de método abreviado deben estar bien documentadas en el contenido de ayuda de la aplicación.

Puede documentar las claves de acceso a través de lectores de pantalla estableciendo la propiedad adjunta AutomationProperties.AccessKey en una cadena que describe la tecla de método abreviado. También hay una propiedad adjunta AutomationProperties.AcceleratorKey para documentar teclas de método abreviado no mnemónicos, aunque los lectores de pantalla suelen tratar ambas propiedades de la misma manera. Intente documentar las teclas de método abreviado de varias maneras, mediante información sobre herramientas, propiedades de automatización y documentación de ayuda escrita.

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 KeyDown="Grid_KeyDown">

  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>

  <MediaElement x:Name="DemoMovie" Source="xbox.wmv"
    Width="500" Height="500" Margin="20" HorizontalAlignment="Center" />

  <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="Control P">
      <TextBlock>Play</TextBlock>
    </Button>

    <Button x:Name="PauseButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+A"
      AutomationProperties.AcceleratorKey="Control A">
      <TextBlock>Pause</TextBlock>
    </Button>

    <Button x:Name="StopButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+S"
      AutomationProperties.AcceleratorKey="Control S">
      <TextBlock>Stop</TextBlock>
    </Button>
  </StackPanel>
</Grid>

Importante

Establecer AutomationProperties.AcceleratorKey o AutomationProperties.AccessKey no habilita la funcionalidad del teclado. Esto solo indica qué claves se deben usar para el marco de Automatización de la interfaz de usuario y, a continuación, se pueden pasar a los usuarios a través de tecnologías de asistencia.

El control de claves se implementa en código subyacente, no en XAML. Todavía tienes que adjuntar controladores para eventos KeyDown o KeyUp en el control pertinente para implementar realmente el comportamiento del método abreviado de teclado en tu aplicación. Además, la decoración de texto subrayado para una tecla de acceso no se proporciona automáticamente. Debe subrayar explícitamente el texto de la clave específica en el formato de subrayado insertado si desea mostrar texto subrayado en la interfaz de usuario.

Por motivos de simplicidad, en el ejemplo anterior se omite el uso de recursos para cadenas como "Ctrl+A". Sin embargo, también debe tener en cuenta las teclas de método abreviado durante la localización. La localización de teclas de método abreviado es relevante porque la elección de la tecla que se va a usar como tecla de método abreviado normalmente depende de la etiqueta de texto visible para el elemento.

Para obtener más instrucciones sobre cómo implementar teclas de método abreviado, 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

Los eventos de entrada (como los eventos clave) usan un concepto de evento denominado eventos enrutados. Un evento enrutado puede propagar por los elementos secundarios de un control compuesto primario, de modo que el control primario pueda controlar eventos para varios elementos secundarios. Este modelo de eventos es cómodo para definir acciones de teclas de método abreviado para un control que contiene varios elementos secundarios, ninguno de los cuales puede tener el foco o formar parte del orden de tabulación.

Para obtener código de ejemplo que muestra cómo escribir un controlador de eventos de clave que incluye la comprobación de modificadores como la tecla Ctrl, vea Interacciones de teclado.

Navegación por teclado para controles personalizados

Se recomienda usar las teclas de dirección como métodos abreviados de teclado para navegar entre elementos secundarios en los casos en los que los elementos secundarios tienen una relación spacial entre sí. Si los nodos de vista de árbol tienen elementos secundarios independientes para controlar la activación de expand-collapse y node, use las teclas de dirección izquierda y derecha para proporcionar la funcionalidad de expansión y contraer teclado. Si tiene un control orientado que admite recorrido direccional dentro del contenido del control, use las teclas de dirección adecuadas.

Por lo general, se implementa el control de claves personalizado para controles personalizados mediante la inclusión de una invalidación de los métodos OnKeyDown y OnKeyUp como parte de la lógica de clase.

Ejemplo de un estado visual para un indicador de foco

Como se mencionó anteriormente, cualquier control personalizado que admita el foco debe tener un indicador de foco visual. Normalmente, ese indicador de foco es simplemente un rectángulo que describe el rectángulo delimitador del control. El rectángulo para el foco visual es un elemento del mismo nivel que el resto de la composición del control en una plantilla de control, pero se establece inicialmente con un valor Visibility de Collapsed porque el control aún no está centrado. Cuando el control obtiene el foco, se invoca un estado visual que establece específicamente la visibilidad del objeto visual de foco en Visible. Una vez que el foco se mueve en otro lugar, se llama a otro estado visual y la visibilidad se contrae.

Todos los controles XAML enfocados muestran un indicador de foco visual adecuado cuando se centra. Los seleccionados por el usuario también pueden afectar a la apariencia del indicador (especialmente si el usuario usa un modo de contraste alto). Si usas los controles XAML en la interfaz de usuario (y no reemplazas las plantillas de control), no necesitas hacer nada adicional para obtener indicadores de foco visual predeterminados. Sin embargo, si tienes intención de volver a simplificar un control, o si tienes curiosidad sobre cómo los controles XAML proporcionan sus indicadores de foco visual, el resto de esta sección explica cómo se hace esto en XAML y la lógica de control.

Este es un ejemplo de XAML que procede de la plantilla XAML predeterminada para un botón.

XAML

<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>

Hasta ahora esto es sólo la composición. Para controlar la visibilidad del indicador de foco, defina los estados visuales que alternan la propiedad Visibility. Esto se hace mediante visualStateManager y la propiedad adjunta VisualStateManager.VisualStateGroups, tal como se aplica al elemento raíz que define la composición.

<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"/>
         </VisualState>
         <VisualState x:Name="Unfocused" />
         <VisualState x:Name="PointerFocused" />
       </VisualStateGroup>
     <VisualStateManager.VisualStateGroups>
<!--composition is here-->
   </Grid>
</ControlTemplate>

Observe cómo solo uno de los estados con nombre ajusta visibilidad directamente, mientras que los demás están aparentemente vacíos. Con los estados visuales, en cuanto el control usa otro estado del mismo VisualStateGroup, las animaciones aplicadas por el estado anterior se cancelan inmediatamente. Dado que la visibilidad predeterminada de la composición es Collapsed, el rectángulo no aparecerá. La lógica de control controla esto escuchando eventos de enfoque como GotFocus y cambiando los estados con GoToState. A menudo, esto ya se controla para usted si usa un control predeterminado o personalización basado en un control que ya tiene ese comportamiento.

Accesibilidad del teclado y dispositivos sin un teclado de hardware

Algunos dispositivos no tienen un teclado de hardware dedicado y se basan en un Panel de entrada temporal (SIP) en su lugar. Los lectores de pantalla pueden leer la entrada de texto del SIP de texto y los usuarios pueden detectar dónde están sus dedos porque el lector de pantalla puede detectar que el usuario está examinando las claves y lee el nombre de la clave escaneada en voz alta. Además, algunos de los conceptos de accesibilidad orientados al teclado se pueden asignar a comportamientos de tecnología de asistencia relacionados que no usan un teclado en absoluto. Por ejemplo, aunque un SIP no incluya una tecla Tab, Narrador admite un gesto táctil equivalente a presionar la tecla Tab, por lo que tener un orden de tabulación útil a través de los controles de una interfaz de usuario sigue siendo crtical para la accesibilidad. Narrador también admite muchos otros gestos táctiles, incluidas las teclas de dirección para navegar dentro de controles complejos (consulte Comandos de teclado narrador y gestos táctiles).

Ejemplos

Sugerencia

La aplicación WinUI 3 Gallery incluye ejemplos interactivos de la mayoría de los controles, características y funcionalidades de WinUI 3. Obtenga la aplicación de Microsoft Store u obtenga el código fuente en GitHub.