Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Use a navegação de foco para fornecer experiências de interação abrangentes e consistentes em seus aplicativos do Windows e controles personalizados para usuários com poder de teclado, pessoas com deficiências e outros requisitos de acessibilidade, bem como a experiência de 3 metros das telas de televisão e do Xbox One.
Visão geral
A navegação de foco refere-se ao mecanismo subjacente que permite que os usuários naveguem e interajam com a interface do usuário de um aplicativo do Windows usando um teclado, gamepad ou controle remoto.
Observação
Os dispositivos de entrada normalmente são classificados como dispositivos de apontamento, como toque, touchpad, caneta e mouse e dispositivos que não apontam, como teclado, gamepad e controle remoto.
Este tópico descreve como otimizar um aplicativo do Windows e criar experiências de interação personalizadas para usuários que dependem de tipos de entrada que não apontam.
Embora nos concentremos na entrada de teclado para controles personalizados em aplicativos do Windows em computadores, uma experiência de teclado bem projetada também é importante para teclados de software, como o teclado virtual e o Teclado Na Tela (OSK), oferecendo suporte a ferramentas de acessibilidade como o Windows Narrador e dando suporte à experiência de 10 pés.
Consulte Manipular entrada do ponteiro para obter diretrizes sobre como criar experiências personalizadas em aplicativos do Windows para dispositivos apontadores.
Para obter informações mais gerais sobre como criar aplicativos e experiências para teclado, consulte Interação com teclado.
Orientação geral
Somente os elementos de interface do usuário que exigem interação do usuário devem dar suporte à navegação de foco, elementos que não exigem uma ação, como imagens estáticas, não precisam de foco no teclado. Leitores de tela e ferramentas de acessibilidade semelhantes ainda anunciam esses elementos estáticos, mesmo quando não estão incluídos na navegação em foco.
É importante lembrar que, ao contrário de navegar com um dispositivo de ponteiro, como um mouse ou toque, a navegação de foco é linear. Ao implementar a navegação de foco, considere como um usuário interagirá com seu aplicativo e qual deve ser a navegação lógica. Na maioria dos casos, recomendamos que o comportamento de navegação de foco personalizado siga o padrão de leitura preferencial da cultura do usuário.
Algumas outras considerações sobre foco de navegação incluem:
- Os controles são agrupados logicamente?
- Há grupos de controles com maior importância?
- Se sim, esses grupos contêm sub-grupos?
- O layout requer navegação direcional personalizada (teclas de direção) e ordem de tabulação?
O eBook Software de Engenharia para Acessibilidade tem um excelente capítulo sobre Projetando a Hierarquia Lógica.
Navegação direcional 2D para teclado
A região de navegação interna 2D de um controle, ou grupo de controle, é conhecida como sua "área direcional". Quando o foco muda para esse objeto, as teclas de seta do teclado (esquerda, direita, para cima e para baixo) podem ser usadas para navegar entre elementos filho dentro da área direcional.
2D Região de navegação interna, ou área direcional, de um grupo de controle
Você pode usar a propriedade XYFocusKeyboardNavigation (que tem valores possíveis de Auto, Habilitado ou Desabilitado) para gerenciar a navegação interna 2D com as teclas de seta do teclado.
Observação
A ordem de tabulação não é afetada por essa propriedade. Para evitar uma experiência de navegação confusa, recomendamos que os elementos filho de uma área direcional não sejam explicitamente especificados na ordem de navegação da guia do aplicativo. Consulte as propriedades UIElement.TabFocusNavigation e TabIndex para obter mais detalhes sobre o comportamento de tabulação de um elemento.
Automático (comportamento padrão)
Quando definido como Automático, o comportamento de navegação direcional é determinado pela ancestralidade do elemento ou pela hierarquia de herança. Se todos os ancestrais estiverem no modo padrão (definido como Automático), a navegação direcional com o teclado não é suportada.
Desactivado
Defina XYFocusKeyboardNavigation como Desabilitado para bloquear a navegação direcional para o controle e seus elementos filho.
Neste exemplo, o StackPanel primário (ContainerPrimary) tem XYFocusKeyboardNavigation definido como Habilitado. Todos os elementos filho herdam essa configuração e podem ser navegados com as setas do teclado. No entanto, os elementos B3 e B4 estão em um StackPanel secundário (ContainerSecondary) com XYFocusKeyboardNavigation definido como Desabilitado, que substitui o contêiner primário e desabilita a navegação das teclas de seta a si mesmo e entre seus elementos-filho.
<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>
Habilitado
Defina XYFocusKeyboardNavigation como Habilitado para dar suporte à navegação direcional 2D para um controle e cada um de seus UIElement objetos filho.
Quando definido, a navegação com as teclas de direção é restrita a elementos dentro da área direcional. A navegação de tabulação não é afetada, pois todos os controles permanecem acessíveis por meio de sua hierarquia de ordem de tabulação.
Comportamento habilitado para XYFocusKeyboardNavigation
Neste exemplo, o StackPanel primário (ContainerPrimary) tem XYFocusKeyboardNavigation definido como Habilitado. Todos os elementos filho herdam essa configuração e podem ser acessados com as teclas de seta. Os elementos B3 e B4 estão em um StackPanel secundário (ContainerSecondary) em que XYFocusKeyboardNavigation não está definido, o que herda a configuração do contêiner primário. O elemento B5 não está dentro de uma área direcional declarada e não dá suporte à navegação de teclas de direção, mas dá suporte ao comportamento de navegação de guia padrão.
<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>
Você pode ter múltiplos níveis de áreas direcionais aninhadas. Se todos os elementos pai tiverem XYFocusKeyboardNavigation definido como Habilitado, os limites da região de navegação interna serão ignorados.
Aqui está um exemplo de duas áreas direcionais aninhadas dentro de um elemento que não dá suporte explicitamente à navegação direcional 2D. Nesse caso, não há suporte para navegação direcional entre as duas áreas aninhadas.
XYFocusKeyboardNavigation habilitado e comportamento aninhado
Aqui está um exemplo mais complexo de três áreas de direção aninhadas em que:
- Quando B1 tem foco, apenas B5 pode ser acessado e o inverso também é verdadeiro, porque há um limite de área direcional onde XYFocusKeyboardNavigation está definido como Desabilitado, tornando B2, B3 e B4 inacessíveis através das teclas de seta
- Quando B2 tem foco, somente é possível navegar para B3 (e vice-versa) porque a barreira da área de navegação impede a navegação com as teclas de direção para B1, B4 e B5
- Quando b4 tem foco, a tecla Tab deve ser usada para navegar entre controles
Comportamento aninhado complexo e habilitado para XYFocusKeyboardNavigation
Navegação entre separadores
Embora as teclas de direção possam ser usadas para navegação direcional 2D em um controle ou grupo de controle, a tecla Tab pode ser usada para navegar entre todos os controles em um aplicativo do Windows.
Todos os controles interativos dão suporte à navegação da tecla Tab por padrão (as propriedades IsEnabled e IsTabStop são true), com a ordem de tabulação lógica derivada do layout de controle em seu aplicativo. No entanto, a ordem padrão não corresponde necessariamente à ordem visual. A posição de exibição real pode depender do contêiner de layout pai e de determinadas propriedades que você pode definir nos elementos filho para influenciar o layout.
Evite uma ordem de tabulação personalizada que faça o foco saltar em seu aplicativo. Por exemplo, uma lista de controles em um formulário deve ter uma ordem de tabulação que flui de cima para baixo e da esquerda para a direita (dependendo da localidade).
Nesta seção, descrevemos como essa ordem de tabulação pode ser totalmente personalizada para atender ao seu aplicativo.
Definir o comportamento de navegação de guia
A propriedade TabFocusNavigation de UIElement especifica o comportamento de navegação de guia para toda a árvore de objetos (ou área direcional).
Observação
Use essa propriedade em vez da propriedade Control.TabNavigation para objetos que não usam um ControlTemplate para definir sua aparência.
Como mencionamos na seção anterior, para evitar uma experiência de navegação confusa, recomendamos que os elementos filho de uma área direcional não sejam explicitamente especificados na ordem de navegação da guia do aplicativo. Consulte as propriedades UIElement.TabFocusNavigation e TabIndex para obter mais detalhes sobre o comportamento de tabulação de um elemento.
Para versões anteriores ao Windows 10 Creators Update (build 10.0.15063), as configurações de guia eram limitadas a objetos ControlTemplate . Para obter mais informações, consulte Control.TabNavigation.
TabFocusNavigation tem um valor do tipo KeyboardNavigationMode com os seguintes valores possíveis (observe que esses exemplos não são grupos de controle personalizados e não exigem navegação interna com as teclas de direção):
Local (padrão), os índices de tabulação são reconhecidos na subárvore local dentro do contêiner. Para este exemplo, a ordem de tabulação é B1, B2, B3, B4, B5, B6, B7, B1.
Comportamento de navegação da guia "Local"
Uma vez O contêiner e todos os elementos filho recebem o foco uma vez. Para este exemplo, a ordem de tabulação é B1, B2, B7, B1 (a navegação interna com a tecla de direção também é demonstrada).
Comportamento de navegação da guia "Uma vez"
Cycle
O foco volta para o elemento focalizável inicial dentro de um contêiner. Para este exemplo, a ordem de tabulação é B1, B2, B3, B4, B5, B6, B2...
Comportamento de navegação da guia "Ciclo"
Este é o código para os exemplos anteriores (com 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 a ordem na qual os elementos recebem foco quando o usuário navega pelos controles usando a tecla Tab. Um componente com um índice de tabulação inferior recebe o foco antes de um componente com um índice mais alto.
Quando um controle não tem nenhum TabIndex especificado, ele recebe um valor de índice mais alto do que o valor de índice mais alto atual (e a prioridade mais baixa) de todos os controles interativos na árvore visual, com base no escopo.
Todos os elementos filhos de um controle são considerados como um escopo, e, se um desses elementos também tiver elementos filhos, eles serão considerados como outro escopo independente. Qualquer ambiguidade é resolvida escolhendo o primeiro elemento na árvore visual do escopo.
Para excluir um controle da ordem de tabulação, defina a propriedade IsTabStop comofalse.
Substitua a ordem de tabulação padrão definindo a propriedade TabIndex .
Observação
TabIndex funciona da mesma maneira com UIElement.TabFocusNavigation e Control.TabNavigation.
Aqui, mostramos como a navegação de foco pode ser afetada pela propriedade TabIndex em elementos específicos.
Navegação na aba "Local" com o comportamento de tabIndex
No exemplo anterior, há dois escopos:
- B1, área direcional (B2 – B6) e B7
- área direcional (B2 – B6)
Quando B3 (na área direcional) recebe o foco, o escopo muda e a navegação por guias é transferida para a área direcional, onde o melhor candidato para o foco subsequente é identificado. Nesse caso, B2 seguido por B4, B5 e B6. O escopo muda novamente e o foco passa para B1.
Este é o código deste exemplo.
<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>
Navegação direcional 2D para teclado, gamepad e controle remoto
Tipos de entrada sem ponteiro, como teclado, gamepad, controle remoto e ferramentas de acessibilidade, como o Windows Narrador, compartilham um mecanismo comum e subjacente para navegar e interagir com a interface do usuário do aplicativo Windows.
Nesta seção, abordaremos como especificar uma estratégia de navegação preferencial e ajustar a navegação de foco em seu aplicativo por meio de um conjunto de propriedades de estratégia de navegação que dão suporte a todos os tipos de entrada sem ponteiro baseados em foco.
Para obter informações mais gerais sobre como criar aplicativos e experiências para Xbox/TV, consulte Interação com Teclado, Design para Xbox e TV e Gamepad e interações de controle remoto.
Estratégias de navegação
As estratégias de navegação são aplicáveis ao teclado, gamepad, controle remoto e várias ferramentas de acessibilidade.
As propriedades de estratégia de navegação a seguir permitem que você influencie qual controle recebe o foco com base na tecla de seta, no botão direcional (D-pad) ou em pressionamentos semelhantes.
- Estratégia de Navegação com Foco para Cima XY (XYFocusUpNavigationStrategy)
- XYFocusDownNavigationStrategy
- XYFocusLeftNavigationStrategy
- XYFocusRightNavigationStrategy
Essas propriedades têm valores possíveis de Auto (padrão), NavigationDirectionDistance, Projection ou RectilinearDistance .
Se definido como Auto, o comportamento do elemento é baseado nos ancestrais do elemento. Se todos os elementos forem definidos como Auto, Projeção será usada.
Observação
Outros fatores, como o elemento anteriormente focado ou a proximidade com o eixo da direção de navegação, podem influenciar o resultado.
Projection
A estratégia projeção move o foco para o primeiro elemento encontrado quando a borda do elemento atualmente focado é projetada na direção da navegação.
Neste exemplo, cada direção de navegação de foco é definida como Projeção. Observe como o foco se move para baixo de B1 para B4, ignorando B3. Isso ocorre porque a B3 não está na zona de projeção. Observe também como um candidato de foco não é identificado ao mover para a esquerda do B1. Isso ocorre porque a posição de B2 em relação a B1 elimina B3 como um candidato. Se b3 estivesse na mesma linha que B2, seria um candidato viável para navegação à esquerda. B2 é um candidato viável devido à sua proximidade desobstruída com o eixo da direção de navegação.
Estratégia de navegação de projeção
NavigationDirectionDistance
A estratégia NavigationDirectionDistance move o foco para o elemento mais próximo do eixo da direção de navegação.
A borda do retângulo de delimitação correspondente à direção de navegação é estendida e projetada para identificar alvos candidatos. O primeiro elemento encontrado é identificado como o destino. No caso de vários candidatos, o elemento mais próximo é identificado como o alvo. Se ainda houver vários candidatos, o elemento mais à esquerda/superior será identificado como o candidato.
Estratégia de navegação NavigationDirectionDistance
RetilinearDistance
A estratégia RectilinearDistance move o foco para o elemento mais próximo com base na distância retilínea 2D (Geometria Taxicab).
A soma da distância primária e da distância secundária para cada candidato em potencial é usada para identificar o melhor candidato. Em um empate, o primeiro elemento à esquerda será selecionado se a direção solicitada for para cima ou para baixo e o primeiro elemento para a parte superior for selecionado se a direção solicitada for esquerda ou direita.
Estratégia de navegação RectilinearDistance
Esta imagem mostra como, quando B1 tem foco e a direção solicitada é para baixo, B3 é o candidato de foco RectilinearDistance. Isso se baseia nas seguintes calcualações para este exemplo:
- A distância (B1, B3, Down) é 10 + 0 = 10
- A distância (B1, B2, Down) é 0 + 40 = 30
- A distância (B1, D, Down) é 30 + 0 = 30
Artigos relacionados
- Navegação de foco programática
- interações de teclado
- Acessibilidade do teclado
Windows developer