Implementando a acessibilidade de teclado (XAML)

Applies to Windows and Windows Phone

Procurando a versão para HTML/JavaScript deste tópico? Veja Implementando a acessibilidade de teclado (HTML).

Muitos usuários que são cegos ou têm problemas de mobilidade usam o teclado como o único meio de navegar no seu aplicativo de interface do usuário e acessar a sua funcionalidade. Se seu aplicativo não oferecer um bom acesso ao teclado, esses usuários terão dificuldade em usar o aplicativo, ou podem não conseguir usá-lo.

Veja este recurso em ação como parte da nossa série sobre recursos para aplicativos, do início ao fim:  Interação do usuário: entrada por toque... e mais

Navegação de teclado entre elementos de interface de usuário

Para usar o teclado com um controle, o controle precisa ter foco e, para receber foco (sem usar um ponteiro), o controle precisa ser acessível em um projeto de interface de usuário da interface do usuário pela navegação por tabulação. Por padrão, a ordem de tabulação dos controles é a mesma ordem que eles foram adicionados à superfície de um projeto, listados em XAML ou adicionados programaticamente a um contêiner.

Na maioria dos casos, a ordem padrão baseada em como você define os controles no XAML é a melhor ordem, principalmente porque é a ordem de leitura dos leitores de tela. Contudo, a ordem padrão não corresponde necessariamente à ordem visual. A posição de exibição real poderia depender do contêiner de layout pai e de certas propriedades que você pode definir nos elementos filhos para influenciar o layout. Para ter certeza de que seu aplicativo tem uma boa ordem de tabulação, teste esse comportamento. Principalmente se você tiver uma metáfora de grade ou de tabela em seu layout, a ordem de leitura dos usuários poderá ser diferente da ordem de tabulação. Nem sempre isso é um problema. No entanto, convém testar a funcionalidade do aplicativo como interface do usuário tanto de toque quanto acessível por teclado e verificar se ela responde igual para ambas as formas.

Você pode fazer com que a ordem de tabulação corresponda à ordem visual ajustando o XAML. Ou pode substituir a ordem de tabulação padrão definindo a propriedade TabIndex, conforme mostrado no exemplo a seguir de um layout de Grid que usa a navegação por guia de primeira coluna.


<!--Custom tab order.--> 
<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>

Você pode desejar excluir um controle da ordem de tabulação. Você normalmente faz isso apenas tornando o controle não interativo, por exemplo, definindo sua propriedade IsEnabled como false. Um controle desabilitado é automaticamente excluído da ordem de tabulação. Às vezes, você pode precisar excluir um controle da ordem de tabulação, mesmo que ele não esteja desabilitado. Nesse caso, você pode definir a propriedade IsTabStop como false.

Todos os elementos que podem ter o foco estão geralmente na ordem de tabulação por padrão. A exceção é que determinados tipos de exibição de texto, como RichTextBlock, podem ter foco para serem acessados pela área de transferência para seleção de texto; no entanto, eles não estão na ordem de tabulação porque elementos de texto estáticos não costumam estar na ordem de tabulação. Normalmente, eles não são interativos (não podem ser invocados nem pedem entrada de texto, mas permitem o Padrão de controle de texto que aceita a localização e o ajuste de pontos de seleção no texto). O texto não deve ter a conotação de que a definição de um foco para ele ativará alguma ação que seja possível. Os elementos de texto ainda serão detectados pelas tecnologias assistenciais e lerão em voz alta em leitores de tela, mas isso depende de técnicas diferentes da busca desses elementos na ordem de tabulação prática.

Independentemente de você ajustar os valores de TabIndex ou usar a ordem padrão, estas regras são aplicáveis:

  • Elementos da interface do usuário com TabIndex igual a 0 são adicionados à ordem de tabulação com base na ordem de declaração no XAML ou nas coleções filhas.
  • Elementos da interface do usuário com TabIndex maior que 0 são adicionados à ordem de tabulação com base no valor de TabIndex.
  • Os elementos da interface do usuário com TabIndex menor que 0 são adicionados à ordem de tabulação e aparecem antes de qualquer valor zero. Isso é bem diferente de como o HTML manipula seu atributo tabindex (e tabindex negativo não era permitido nas especificações HTML antigas).

Navegação de teclado entre elementos de interface de usuário

Para os elementos compostos, é importante garantir uma navegação interior adequada entre os elementos contidos. Um elemento composto pode gerenciar seu filho ativo atual para reduzir a sobrecarga de ter todas os elementos filhos com capacidade de foco. Esse elemento composto é incluído na ordem de guias e trata os eventos de navegação de teclado sozinho. Muitos dos controles compostos que você usa para um aplicativo do Tempo de Execução do Windows em C++, C# ou Visual Basic já têm alguma lógica de navegação interna incorporada à manipulação de eventos do controle. Por exemplo, a passagem por seta-chave de itens é habilitada por padrão para os itens de um controle ItemsControl.

Alternativas de teclado para ações do ponteiro e eventos para elementos de controle específico

Permita que os elementos de interface de usuário que podem ser clicados também possam ser invocados usando o teclado. Para usar o teclado com um elemento da interface do usuário, o elemento deve ter foco. Somente as classes que derivam de Control suportam o foco e a navegação de guias.

Para os elementos de interface do usuário que podem ser invocados, implemente manipuladores de eventos de teclado para as teclas de barra de espaço e Enter. Isso torna o suporte de acessibilidade básica de teclado completo e permite que os usuários utilizem cenários básicos de aplicativos apenas com o teclado, ou seja, os usuários podem acessar todos os elementos interativos da interface do usuário e ativar a funcionalidade padrão.

Em casos onde um elemento que você deseja usar na interface do usuário não pode ter foco, você pode criar seu próprio controle personalizado. Você deve definir a propriedade IsTabStop como true para habilitar o foco e deve fornecer uma indicação visual do estado do foco criando um estado visual que decora a interface do usuário com um indicador de foco. Contudo, é frequentemente mais fácil usar a composição de controle, para que o suporte para paradas de tabulação, foco e pares e padrões de Automação de Interface do Usuário da Microsoft possa ser tratados pelo controle no qual você escolhe compor o seu conteúdo.

Por exemplo, em vez de tratar um evento pressionado por ponteiro em um Image, você poderia envolver esse elemento em um Button para conseguir suporte ao ponteiro, teclado e foco.


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

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

Atalhos do teclado

Além de implementar a navegação pelo teclado e ativação para o seu aplicativo, é recomendável implementar atalhos para a funcionalidade do seu aplicativo. A navegação por tabulação fornece um bom nível básico de suporte ao teclado, mas com formulários complexos, você poderia desejar adicionar suporte às teclas de atalho também. Isso pode tornar o seu aplicativo mais eficiente para usar, mesmo para as pessoas que usam dispositivos de teclado e de ponteiro.

Um atalho é uma combinação de teclas que aumenta a produtividade, fornecendo uma maneira eficiente de o usuário acessar a funcionalidade do aplicativo. Existem dois tipos de atalho:

  • Uma tecla de acesso é um atalho para um elemento da interface do usuário no seu aplicativo. Teclas de acesso consistem na tecla Alt mais uma tecla de letra.
  • Uma tecla aceleradora é um atalho para um comando do aplicativo. Seu aplicativo pode ter uma interface do usuário que corresponde exatamente ao comando. Teclas aceleradoras consistem na tecla Ctrl mais uma tecla de letra.

É fundamental oferecer aos usuários que dependem de leitores de tela e outras tecnologias assistenciais uma maneira fácil de descobrir as teclas de atalho do seu aplicativo. Comunique as teclas de atalho usando na dicas de ferramentas, nomes acessíveis, descrições acessíveis ou alguma outra forma de comunicação na tela. No mínimo, as teclas de atalho devem ser bem documentadas no conteúdo de Ajuda do seu aplicativo.

Você pode documentar as teclas de acesso através dos leitores de tela definindo a propriedade anexada AutomationProperties.AccessKey para uma cadeia de caracteres que descreve a tecla de atalho. Há também uma propriedade anexada AutomationProperties.AcceleratorKey para documentar teclas de atalho não mnemônicas, apesar de leitores de tela geralmente tratarem as duas propriedades da mesma forma. Tente documentar as teclas de atalho de várias formas, usando dicas de ferramentas, propriedades de automação e documentação de Ajuda escrita.

O seguinte exemplo demonstra como documentar as teclas de atalho dos botões de reproduzir, pausar e parar mídia.


<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  A definição de AutomationProperties.AcceleratorKey ou AutomationProperties.AccessKey não habilita a funcionalidade de teclado. Ela só relata à estrutura de Automação da Interface do Usuário quais teclas devem ser usadas, para que essas informações possam ser repassadas aos usuários através de tecnologias assistivas. A implementação referente à manipulação de teclas ainda precisa ser feita em código, e não em XAML. Você ainda precisa anexar manipuladores para eventos KeyDown ou KeyUp no controle relevante para realmente implementar o comportamento de atalhos de teclado em seu aplicativo. Além disso, a decoração de texto sublinhado para uma tecla de acesso não é fornecida automaticamente. Você deve sublinhar explicitamente o texto para a tecla específica em seu mnemônico como formatação Underline embutida se quiser mostrar texto sublinhado na interface do usuário.

Para fins de simplicidade, o exemplo anterior omite o uso de recursos para cadeias de caracteres, como "Ctrl+A". Contudo, considere também as teclas de atalho durante o processo de localização. A localização de teclas de atalho é relevante porque a escolha da chave a ser usada como a chave de atalho normalmente depende do rótulo de texto visível para o elemento. Para saber mais, veja Globalizando seu aplicativo.

Para saber mais sobre as diretrizes de implementação de teclas de atalho, veja Teclas de atalho nas Diretrizes de interação com a experiência do usuário do Windows.

Implementando um manipulador de eventos de chave

Os eventos de entrada, como eventos de chave, usam um conceito de evento denominado eventos roteados. Um evento roteado pode emergir por meio de elementos filho de um controle composto, de tal forma que um pai de controle comum possa manipular eventos para vários elementos filhos. Esse modelo de evento é conveniente para definir ações de teclas de atalho para um controle que contém várias partes compostas que não podem ter foco ou fazer parte da ordem de tabulação.

Para obter um exemplo de código que mostra como escrever um manipulador de eventos de tecla que inclui a verificação de modificadores como a tecla Ctrl, veja Respondendo à entrada por teclado.

Para saber mais sobre o conceito geral de evento roteado, veja Visão geral de eventos e eventos roteados.

Navegação de teclado para controles personalizados

Recomendamos o uso de teclas de direção como atalhos de teclado para navegar entre os elementos filho, nos casos onde os elementos filho têm uma relação espacial entre si. Se os nós de exibição de árvore tiverem subelementos diferentes para lidar com expansão– e recolhimento e ativação de nós, use as teclas de seta para esquerda e direita para obter a –funcionalidade de expansão e recolhimento. Se você tem um controle orientado que oferece suporte à passagem direcional dentro do conteúdo de controle, use as teclas de direção adequadas.

Geralmente, você implementa a manipulação de chave personalizada para controles personalizados incluindo uma substituição dos métodosOnKeyDown e OnKeyUp como parte da lógica da classe.

Um exemplo do estado visual de um indicador de foco

Mencionamos anteriormente que qualquer controle personalizado que habilita o usuário a focá-lo deve ter um indicador de foco visual. Normalmente esse indicador de foco é tão simples quanto desenhar uma forma de retângulo imediatamente ao redor do retângulo delimitador normal do controle. A Rectangle de foco visual é um elemento de par no restante da composição do controle em um modelo de controle, mas é definida inicialmente com um valor Visibility de Collapsed porque o controle não tem foco ainda. Depois, quando o controle obtém o foco, é invocado um estado visual que define especificamente a Visibility do foco visual como Visible. Depois que o foco é movido para outro lugar, outro estado visual é chamado, e a Visibility se torna Collapsed.

Todos os controles XAML padrão referentes ao Tempo de Execução do Windows exibem um indicador de foco visual adequado quando estão em foco (se puderem ser focalizados). Há também aparências significativamente distintas, dependendo do tema selecionado pelo usuário (principalmente se o usuário utilizar o modo de alto contraste.) Se você usa os controles XAML em sua interface do usuário e não substituir os modelos de controle, não terá que fazer nada mais para obter os indicadores de foco visual nos controles que têm comportamento e aparência corretos. Mas se você pretende criar um novo modelo para um controle ou se tiver curiosidade para saber como os controles XAML fornecem os indicadores de foco visual, o restante desta seção explica como isso é feito no XAML e na lógica de controle.

Aqui estão alguns exemplos de XAML provenientes do modelo XAML padrão do Tempo de Execução do Windows para um Button.


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


Até o momento, essa é apenas a composição. Para controlar a visibilidade do indicador do foco, defina os estados visuais que alternam a propriedade Visibility. Para fazer isso, use a propriedade anexada VisualStateManager.VisualStateGroups, conforme aplicada ao elemento raiz que define a composição.


<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 como somente um dos estados nomeados ajusta a Visibility diretamente, enquanto os outros estão aparentemente vazios. A maneira como os estados visuais funcionam é que, tão logo o controle use outro estado da mesma classe VisualStateGroup, todas as animações aplicadas pelo estado anterior são canceladas imediatamente. Como a Visibility padrão da composição é Collapsed, isso significa que o retângulo não aparecerá. A lógica de controle controla isso escutando eventos de foco como GotFocus e mudando os estados com GoToState. Muitas vezes, isso já é manipulado por você, se você está usando um controle padrão ou personalizando com base em um controle que já tem esse comportamento. Para saber mais sobre como usar estados visuais, veja Animações de storyboard para estados visuais.

Acessibilidade do teclado e Windows Phone

Um dispositivo Windows Phone normalmente não tem um teclado de hardware dedicado. Porém, um SIP (Painel de Entrada Virtual) pode oferecer suporte a vários cenários de acessibilidade do teclado. Os leitores de tela podem ler entradas de texto no SIP Texto, incluindo exclusões de anúncio. Os usuários podem saber onde os seus dedos estão, pois o leitor de tela pode detectar se o usuário está usando as teclas e lê o nome da tecla pressionada em voz alta. Além disso, alguns dos conceitos de acessibilidade orientados pelo teclado podem ser mapeados com os comportamentos de tecnologia assistencial relacionados que não usam teclado. Por exemplo, mesmo que um SIP não inclua uma tecla Tab, o Narrador reconhece um gesto de toque que é o equivalente a pressionar a tecla Tab, de modo que ter uma ordem de tabulação útil pelos controles em uma interface do usuário ainda é um princípio importante de acessibilidade. As teclas de setas que são usadas para navegar pelas partes dentro de controles complexos também são suportadas por meio de gestos de toque do Narrador. Quando o foco atinge um controle que não seja entrada de texto, o Narrador suporta um gesto que chama a ação desse controle.

Atalhos do teclado não são muito relevantes para os aplicativos do Windows Phone, pois, um SIP não inclui as teclas Control ou Alt.

Tópicos relacionados

Reagindo à entrada do teclado
Entrada: amostra de teclado virtual
Respondendo ao aparecimento da amostra de teclado na tela
Exemplo de acessibilidade XAML
Animações com storyboard para estados visuais

 

 

Mostrar:
© 2014 Microsoft