Partilhar via


Aceleradores de teclado

Imagem heroica do teclado Surface

As teclas aceleradoras (ou aceleradoras de teclado) são atalhos de teclado que melhoram a usabilidade e acessibilidade das suas aplicações Windows, proporcionando uma forma intuitiva para os utilizadores invocarem ações ou comandos comuns sem terem de navegar pela interface da aplicação.

Observação

Um teclado é indispensável para utilizadores com certas deficiências (ver Acessibilidade do teclado) e é também uma ferramenta importante para quem o prefere como uma forma mais eficiente de interagir com uma aplicação.

Consulte o tópico Teclas de Acesso para detalhes sobre como navegar na interface de uma aplicação Windows com atalhos de teclado.

Para criar os seus próprios atalhos de teclado personalizados, consulte o tópico Eventos de Teclado .

Visão geral

Os aceleradores são compostos por dois tipos de chaves: modificadores e não modificadores. As teclas modificadoras incluem Shift, Menu, Control e a tecla Windows, que são expostas através dos VirtualKeyModifiers. Os não-modificadores incluem qualquer VirtualKey, como Delete, F3, Barra de Espaço, Seta, Esc, e todas as teclas alfanuméricas e de pontuação.

Observação

Os aceleradores normalmente incluem as teclas de função F1 a F12 ou alguma combinação de uma tecla padrão emparelhada com uma ou mais teclas modificadoras (CTRL, Shift). Por exemplo, se um utilizador pressionar Ctrl+Shift+M, o framework verifica os modificadores (Ctrl e Shift) e dispara o acelerador, caso exista.

Muitos controlos XAML têm aceleradores de teclado incorporados. Por exemplo, o ListView suporta Ctrl+A para selecionar todos os itens da lista, e o RichEditBox suporta Ctrl+Tab para inserir um Tab na caixa de texto. Estes aceleradores de teclado incorporados são designados aceleradores de controlo e são executados apenas se o foco estiver sobre o elemento ou num dos seus elementos filho. Aceleradores definidos por ti usando as APIs de aceleradores de teclado aqui discutidas são referidos como aceleradores de aplicações.

Aceleradores de teclado não estão disponíveis para todas as ações, mas estão frequentemente associados a comandos expostos nos menus (e devem ser especificados com o conteúdo do item do menu). Aceleradores também podem ser associados a ações que não têm itens equivalentes no menu. No entanto, como os utilizadores dependem dos menus de uma aplicação para descobrir e aprender o conjunto de comandos disponível, deve tentar tornar a descoberta de aceleradores o mais fácil possível (usar etiquetas ou padrões estabelecidos pode ajudar nisso).

Um acelerador repete-se automaticamente (por exemplo, quando o utilizador pressiona Ctrl+Shift e depois mantém pressionado M, o acelerador é ativado repetidamente até que M seja libertado). Este comportamento não pode ser alterado.

Captura de ecrã dos aceleradores de teclado numa etiqueta de item do menu.
Aceleradores de teclado descritos numa etiqueta de item de menu

Quando usar aceleradores de teclado

Recomendamos que especifique aceleradores de teclado sempre que apropriado na sua interface de utilizador e suporte aceleradores em todos os controlos personalizados.

  • Aceleradores de teclado tornam a sua aplicação mais acessível para utilizadores com deficiências motoras, incluindo aqueles que só conseguem pressionar uma tecla de cada vez ou têm dificuldade em usar o rato.

    Uma interface de teclado bem desenhada é um aspeto importante da acessibilidade ao software. Permite que utilizadores com deficiências visuais ou com certas deficiências motoras naveguem numa aplicação e interajam com as suas funcionalidades. Esses utilizadores podem não conseguir operar um rato e, em vez disso, depender de várias tecnologias assistivas, como ferramentas de melhoria de teclado, teclados no ecrã, ampliadores de ecrã, leitores de ecrã e utilidades de entrada por voz. Para estes utilizadores, uma cobertura abrangente de comandos é crucial.

  • Aceleradores de teclado tornam a sua aplicação mais utilizável para utilizadores avançados que preferem interagir através do teclado.

    Utilizadores experientes têm frequentemente uma forte preferência pelo teclado porque os comandos baseados no teclado podem ser introduzidos mais rapidamente e não exigem que retirem as mãos do teclado. Para estes utilizadores, a eficiência e a consistência são cruciais; A abrangência é importante apenas para os comandos mais usados.

Especificar um acelerador de teclado

Utilize as APIs KeyboardAccelerator para criar aceleradores de teclado em aplicações do Windows. Com estas APIs, não precisa de gerir múltiplos eventos KeyDown para detetar a combinação de teclas pressionada, e pode localizar aceleradores nos recursos da aplicação.

Recomendamos que defina aceleradores de teclado para as ações mais comuns na sua app e as documente usando a etiqueta do item do menu ou o tooltip. Neste exemplo, declaramos aceleradores de teclado apenas para os comandos Renomear e Copiar.

<CommandBar Margin="0,200" AccessKey="M">
  <AppBarButton 
    Icon="Share" 
    Label="Share" 
    Click="OnShare" 
    AccessKey="S" />
  <AppBarButton 
    Icon="Copy" 
    Label="Copy" 
    ToolTipService.ToolTip="Copy (Ctrl+C)" 
    Click="OnCopy" 
    AccessKey="C">
    <AppBarButton.KeyboardAccelerators>
      <KeyboardAccelerator 
        Modifiers="Control" 
        Key="C" />
    </AppBarButton.KeyboardAccelerators>
  </AppBarButton>

  <AppBarButton 
    Icon="Delete" 
    Label="Delete" 
    Click="OnDelete" 
    AccessKey="D" />
  <AppBarSeparator/>
  <AppBarButton 
    Icon="Rename" 
    Label="Rename" 
    ToolTipService.ToolTip="Rename (F2)" 
    Click="OnRename" 
    AccessKey="R">
    <AppBarButton.KeyboardAccelerators>
      <KeyboardAccelerator 
        Modifiers="None" Key="F2" />
    </AppBarButton.KeyboardAccelerators>
  </AppBarButton>

  <AppBarButton 
    Icon="SelectAll" 
    Label="Select" 
    Click="OnSelect" 
    AccessKey="A" />
  
  <CommandBar.SecondaryCommands>
    <AppBarButton 
      Icon="OpenWith" 
      Label="Sources" 
      AccessKey="S">
      <AppBarButton.Flyout>
        <MenuFlyout>
          <ToggleMenuFlyoutItem Text="OneDrive" />
          <ToggleMenuFlyoutItem Text="Contacts" />
          <ToggleMenuFlyoutItem Text="Photos"/>
          <ToggleMenuFlyoutItem Text="Videos"/>
        </MenuFlyout>
      </AppBarButton.Flyout>
    </AppBarButton>
    <AppBarToggleButton 
      Icon="Save" 
      Label="Auto Save" 
      IsChecked="True" 
      AccessKey="A"/>
  </CommandBar.SecondaryCommands>

</CommandBar>

Captura de ecrã de um acelerador de teclado numa tooltip.
Acelerador de teclado descrito numa dica de ferramenta

O objeto UIElement tem uma coleção KeyboardAccelerator , KeyboardAccelerators, onde especifica os seus objetos personalizados KeyboardAccelerator e define as teclas para o acelerador de teclado:

Observação

São suportados aceleradores de tecla única (A, Delete, F2, barra de espaço, Esc, tecla multimédia) e aceleradores multitecla (Ctrl+Shift+M). No entanto, as teclas virtuais do Gamepad não são suportadas.

Aceleradores com mira

Alguns aceleradores funcionam apenas em setos específicos, enquanto outros funcionam em toda a aplicação.

Por exemplo, o Microsoft Outlook inclui os seguintes aceleradores:

  • Ctrl+B, Ctrl+I e ESC funcionam apenas no âmbito do formulário de enviar email
  • Ctrl+1 e Ctrl+2 funcionam em toda a aplicação

Menus de contexto

As ações do menu de contexto afetam apenas áreas ou elementos específicos, como os caracteres selecionados num editor de texto ou uma música numa playlist. Por esta razão, recomendamos definir o âmbito dos aceleradores de teclado dos itens do menu de contexto para o elemento pai deste menu.

Use a propriedade ScopeOwner para especificar o âmbito do acelerador de teclado. Este código demonstra como implementar um menu de contexto numa ListView com aceleradores de teclado delimitados.

<ListView x:Name="MyList">
  <ListView.ContextFlyout>
    <MenuFlyout>
      <MenuFlyoutItem Text="Share" Icon="Share"/>
      <MenuFlyoutItem Text="Copy" Icon="Copy">
        <MenuFlyoutItem.KeyboardAccelerators>
          <KeyboardAccelerator 
            Modifiers="Control" 
            Key="C" 
            ScopeOwner="{x:Bind MyList }" />
        </MenuFlyoutItem.KeyboardAccelerators>
      </MenuFlyoutItem>
      
      <MenuFlyoutItem Text="Delete" Icon="Delete" />
      <MenuFlyoutSeparator />
      
      <MenuFlyoutItem Text="Rename">
        <MenuFlyoutItem.KeyboardAccelerators>
          <KeyboardAccelerator 
            Modifiers="None" 
            Key="F2" 
            ScopeOwner="{x:Bind MyList}" />
        </MenuFlyoutItem.KeyboardAccelerators>
      </MenuFlyoutItem>
      
      <MenuFlyoutItem Text="Select" />
    </MenuFlyout>
    
  </ListView.ContextFlyout>
    
  <ListViewItem>Track 1</ListViewItem>
  <ListViewItem>Alternative Track 1</ListViewItem>

</ListView>

O atributo ScopeOwner do elemento MenuFlyoutItem.KeyboardAccelerators identifica o acelerador como de âmbito restrito em vez de global (sendo o padrão nulo, ou global). Para mais detalhes, veja a secção Resolver aceleradores mais adiante neste tópico.

Invocar um acelerador de teclado

O objeto KeyboardAccelerator utiliza o padrão de controlo UI Automation (UIA) para agir quando um acelerador é invocado.

Os padrões de controlo da UIA expõem funcionalidades comuns de controlo. Por exemplo, o controlo Botão implementa o padrão de controlo Invoke para suportar o evento Click (normalmente um controlo é invocado clicando, clicando duas vezes ou pressionando Enter, teclas de atalho pré-definidas ou outra combinação de pressionamentos de teclas). Quando um acelerador de teclado é usado para invocar um controlo, a framework XAML verifica se o controlo implementa o padrão de controlo Invoke e, em caso afirmativo, ativa-o (não é necessário ouvir o evento KeyboardAcceleratorInvoked).

No exemplo seguinte, Control+S aciona o evento Click porque o botão implementa o padrão Invoke.

<Button Content="Save" Click="OnSave">
  <Button.KeyboardAccelerators>
    <KeyboardAccelerator Key="S" Modifiers="Control" />
  </Button.KeyboardAccelerators>
</Button>

Se um elemento implementar múltiplos padrões de controlo, apenas um pode ser ativado através de um acelerador. Os padrões de controlo são priorizados da seguinte forma:

  1. Invocar (Botão)
  2. Alternar (Caixa de Verificação)
  3. Seleção (ListView)
  4. Expandir/Colapsar (Caixa de Combinação)

Se não for identificada correspondência, o acelerador é inválido e é fornecida uma mensagem de depuração ("Não foram encontrados padrões de automação para este componente. Implemente todo o comportamento desejado no evento Invocado. Definir Handled para true no seu gestor de eventos suprime esta mensagem.")

Comportamento personalizado do acelerador de teclado

O evento Invoked do objeto KeyboardAccelerator é ativado quando o acelerador é executado. O objeto evento KeyboardAcceleratorInvokedEventArgs inclui as seguintes propriedades:

  • Handled (Booleano): Definir isto como true impede que o evento desencadeie o padrão de controlo e impede o evento do acelerador de borbulhar. O padrão é "false".
  • Elemento (DependencyObject): O objeto associado ao acelerador.
  • KeyboardAccelerator: O acelerador de teclado usado para ativar o evento Invocado.

Aqui demonstramos como definir uma coleção de aceleradores de teclado para itens numa ListView, e como gerir o evento Invocado para cada acelerador.

<ListView x:Name="MyListView">
  <ListView.KeyboardAccelerators>
    <KeyboardAccelerator Key="A" Modifiers="Control,Shift" Invoked="SelectAllInvoked" />
    <KeyboardAccelerator Key="F5" Invoked="RefreshInvoked"  />
  </ListView.KeyboardAccelerators>
</ListView>
void SelectAllInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
  MyListView.SelectAll();
  args.Handled = true;
}

void RefreshInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
  MyListView.SelectionMode = ListViewSelectionMode.None;
  MyListView.SelectionMode = ListViewSelectionMode.Multiple;
  args.Handled = true;
}

Sobrepor comportamento padrão do teclado

Alguns controlos, quando têm foco, suportam aceleradores de teclado incorporados que substituem qualquer acelerador definido pela aplicação. Por exemplo, quando uma TextBox tem foco, o acelerador Control+C só copia o texto atualmente selecionado (os aceleradores definidos pela aplicação são ignorados e nenhuma outra funcionalidade é executada).

Embora não recomendemos substituir comportamentos padrão de controlo devido à familiaridade e expectativas do utilizador, pode substituir o acelerador de teclado incorporado de um controlo. O exemplo seguinte mostra como substituir o acelerador de teclado Control+C para uma TextBox através do manipulador de eventos PreviewKeyDown:

 private void TextBlock_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
 {
    var ctrlState = CoreWindow.GetForCurrentThread().GetKeyState(Windows.System.VirtualKey.Control);
    var isCtrlDown = ctrlState == CoreVirtualKeyStates.Down || ctrlState 
        ==  (CoreVirtualKeyStates.Down | CoreVirtualKeyStates.Locked);
    if (isCtrlDown && e.Key == Windows.System.VirtualKey.C)
    {
        // Your custom keyboard accelerator behavior.
        
        e.Handled = true;
    }
 }

Desativar um acelerador de teclado

Se um controlo estiver desativado, o acelerador associado também é desativado. No exemplo seguinte, como a propriedade IsEnabled do ListView está definida como falsa, o acelerador Control+A associado não pode ser invocado.

<ListView >
  <ListView.KeyboardAccelerators>
    <KeyboardAccelerator Key="A"
      Modifiers="Control"
      Invoked="CustomListViewSelecAllInvoked" />
  </ListView.KeyboardAccelerators>
  
  <TextBox>
    <TextBox.KeyboardAccelerators>
      <KeyboardAccelerator 
        Key="A" 
        Modifiers="Control" 
        Invoked="CustomTextSelecAllInvoked" 
        IsEnabled="False" />
    </TextBox.KeyboardAccelerators>
  </TextBox>

<ListView>

Os controlos dos pais e dos filhos podem partilhar o mesmo acelerador. Neste caso, o controlo parental pode ser invocado mesmo que a criança tenha foco e o seu acelerador esteja desativado.

Leitores de ecrã e aceleradores de teclado

Leitores de ecrã como o Narrator podem anunciar a combinação de teclas do acelerador do teclado aos utilizadores. Por defeito, isto corresponde a cada modificador (na ordem enum dos VirtualModifiers) seguido da chave (e separado por sinais "+"). Pode personalizar isto através da propriedade AcceleratorKey associada a AutomationProperties. Se for especificado mais do que um acelerador, apenas o primeiro é anunciado.

Neste exemplo, a AutomationProperty.AcceleratorKey devolve a cadeia "Control+Shift+A":

<ListView x:Name="MyListView">
  <ListView.KeyboardAccelerators>

    <KeyboardAccelerator 
      Key="A" 
      Modifiers="Control,Shift" 
      Invoked="CustomSelectAllInvoked" />
      
    <KeyboardAccelerator 
      Key="F5" 
      Modifiers="None" 
      Invoked="RefreshInvoked" />

  </ListView.KeyboardAccelerators>

</ListView>   

Observação

Definir AutomationProperties.AcceleratorKey não ativa funcionalidade do teclado, apenas indica ao framework UIA quais as teclas usadas.

Aceleradores de Teclado Comuns

Recomendamos que torne os aceleradores de teclado consistentes em todas as aplicações Windows.

Os utilizadores têm de memorizar aceleradores de teclado e esperar os mesmos (ou semelhantes) resultados, mas isso pode nem sempre ser possível devido às diferenças de funcionalidade entre aplicações.

Edição Acelerador de Teclado Comum
Iniciar modo de edição Ctrl + E
Selecione todos os itens num controlo ou janela focado Ctrl + A
Pesquisar e substituir Ctrl + H
Desfazer Ctrl + Z
Redo Ctrl + Y
Apagar a seleção e copiá-la para a prancheta Ctrl + X
Copiar a seleção para a prancheta Ctrl + C, Ctrl + Insert
Cole o conteúdo da prancheta Ctrl + V, Shift + Insert
Cola o conteúdo da prancheta (com opções) Ctrl + Alt + V
Renomear um item F2
Adicionar um novo item Ctrl + N
Adicionar um novo item secundário Ctrl + Shift + N
Eliminar item selecionado (com desfazer) Del, Ctrl+D
Eliminar item selecionado (sem desfazer) Shift + Del
Bold Ctrl + B
Sublinhado Ctrl + U
Itálico Ctrl + I
Navegação
Encontre conteúdo num controlo focado ou numa janela Ctrl + F
Ir para o próximo resultado de pesquisa F3
Vai para o próximo painel da interface F6
Vai ao painel da interface anterior Shift + F6
Outras Ações
Adicionar favoritos Ctrl + D
Atualizar F5 ou Ctrl + R
Aumentar o zoom Ctrl + +
Reduzir o zoom Ctrl + -
Ampliar para a vista padrão Ctrl + 0
Save Ctrl + S
Close Ctrl + W
Print Ctrl + P

Note que algumas das combinações não são válidas para versões localizadas do Windows. Por exemplo, na versão espanhola do Windows, Ctrl+N é usado para negrito em vez de Ctrl+B. Recomendamos fornecer aceleradores de teclado localizados se a aplicação for localizada.

Possibilidades de usabilidade para aceleradores de teclado

Tooltips

Como os aceleradores de teclado normalmente não são descritos diretamente na interface da sua aplicação Windows, pode melhorar a descoberta através de dicas de ferramenta, que aparecem automaticamente quando o utilizador move o foco, pressiona e segura, ou faz pairar o ponteiro do rato sobre um controlo. A dica de ferramenta pode identificar se um controlo tem um acelerador de teclado associado e, em caso afirmativo, qual é a combinação de teclas do acelerador.

Windows 10, Versão 1803 (Atualização de abril de 2018) e versões posteriores

Por defeito, quando os aceleradores de teclado são declarados, todos os controlos (exceto MenuFlyoutItem e ToggleMenuFlyoutItem) apresentam as combinações de teclas correspondentes numa tooltip.

Observação

Se um controlo tiver mais do que um acelerador definido, apenas o primeiro é apresentado.

Captura de ecrã de um botão Guardar com uma dica de ferramenta acima que indica suporte para a combinação de teclas Ctrl+S.
Combinação de teclas do acelerador na dica de ferramenta

Para os objetos Button, AppBarButton e AppBarToggleButton, o acelerador do teclado é adicionado à dica de ferramenta padrão do controlo. Para os objetos MenuFlyoutItem e ToggleMenuFlyoutItem , o acelerador do teclado é apresentado com o texto do flyout.

Observação

Especificar uma dica de ferramenta (ver Button1 no exemplo seguinte) substitui este comportamento.

<StackPanel x:Name="Container" Grid.Row="0" Background="AliceBlue">
    <Button Content="Button1" Margin="20"
            Click="OnSave" 
            KeyboardAcceleratorPlacementMode="Auto" 
            ToolTipService.ToolTip="Tooltip">
        <Button.KeyboardAccelerators>
            <KeyboardAccelerator  Key="A" Modifiers="Windows"/>
        </Button.KeyboardAccelerators>
    </Button>
    <Button Content="Button2"  Margin="20"
            Click="OnSave" 
            KeyboardAcceleratorPlacementMode="Auto">
        <Button.KeyboardAccelerators>
            <KeyboardAccelerator  Key="B" Modifiers="Windows"/>
        </Button.KeyboardAccelerators>
    </Button>
    <Button Content="Button3"  Margin="20"
            Click="OnSave" 
            KeyboardAcceleratorPlacementMode="Auto">
        <Button.KeyboardAccelerators>
            <KeyboardAccelerator  Key="C" Modifiers="Windows"/>
        </Button.KeyboardAccelerators>
    </Button>
</StackPanel>

Captura de ecrã de três botões rotulados Button1, Button2 e Button3 com uma dica acima do Button2 que indica suporte para o acelerador Windows+B.

Combinação de teclas de atalho adicionada ao texto de ajuda padrão do botão

<AppBarButton Icon="Save" Label="Save">
    <AppBarButton.KeyboardAccelerators>
        <KeyboardAccelerator Key="S" Modifiers="Control"/>
    </AppBarButton.KeyboardAccelerators>
</AppBarButton>

Captura de ecrã de um botão com um ícone de disco e uma dica de ferramenta que inclui o texto predefinido de Guardar anexado com o acelerador Ctrl+S entre parênteses.

Tecla de atalho adicionada ao tooltip padrão do AppBarButton

<AppBarButton AccessKey="R" Icon="Refresh" Label="Refresh" IsAccessKeyScope="True">
    <AppBarButton.Flyout>
        <MenuFlyout>
            <MenuFlyoutItem AccessKey="A" Icon="Refresh" Text="Refresh A">
                <MenuFlyoutItem.KeyboardAccelerators>
                    <KeyboardAccelerator Key="R" Modifiers="Control"/>
                </MenuFlyoutItem.KeyboardAccelerators>
            </MenuFlyoutItem>
            <MenuFlyoutItem AccessKey="B" Icon="Globe" Text="Refresh B" />
            <MenuFlyoutItem AccessKey="C" Icon="Globe" Text="Refresh C" />
            <MenuFlyoutItem AccessKey="D" Icon="Globe" Text="Refresh D" />
            <ToggleMenuFlyoutItem AccessKey="E" Icon="Globe" Text="ToggleMe">
                <MenuFlyoutItem.KeyboardAccelerators>
                    <KeyboardAccelerator Key="Q" Modifiers="Control"/>
                </MenuFlyoutItem.KeyboardAccelerators>
            </ToggleMenuFlyoutItem>
        </MenuFlyout>
    </AppBarButton.Flyout>
</AppBarButton>

Captura de ecrã de um Menu com MenuFlyoutItens que incluem combinações de teclas aceleradoras.
Combinação de teclas aceleradoras adicionada ao texto do MenuFlyoutItem

Controla o comportamento da apresentação usando a propriedade KeyboardAcceleratorPlacementMode , que aceita dois valores: Auto ou Hidden.

<Button Content="Save" Click="OnSave" KeyboardAcceleratorPlacementMode="Auto">
    <Button.KeyboardAccelerators>
        <KeyboardAccelerator Key="S" Modifiers="Control" />
    </Button.KeyboardAccelerators>
</Button>

Em alguns casos, pode ser necessário apresentar uma dica de ferramenta relativa a outro elemento (tipicamente um objeto contentor).

Aqui, mostramos como usar a propriedade KeyboardAcceleratorPlacementTarget para exibir a combinação de teclas do acelerador do teclado para um botão Guardar, utilizando o contentor Grid em vez do próprio botão.

<Grid x:Name="Container" Padding="30">
  <Button Content="Save"
    Click="OnSave"
    KeyboardAcceleratorPlacementMode="Auto"
    KeyboardAcceleratorPlacementTarget="{x:Bind Container}">
    <Button.KeyboardAccelerators>
      <KeyboardAccelerator  Key="S" Modifiers="Control" />
    </Button.KeyboardAccelerators>
  </Button>
</Grid>

Rótulos / Etiquetas

Em alguns casos, recomendamos usar a etiqueta de um controlo para identificar se o controlo tem um acelerador de teclado associado e, em caso afirmativo, qual é a combinação da tecla aceleradora.

Alguns controlos de plataforma fazem isto por defeito, especificamente os objetos MenuFlyoutItem e ToggleMenuFlyoutItem, enquanto o AppBarButton e o AppBarToggleButton o fazem quando aparecem no menu de transbordo da CommandBar.

Aceleradores de teclado descritos numa etiqueta de item de menu.
Aceleradores de teclado descritos numa etiqueta de item de menu

Pode sobrescrever o texto do acelerador predefinido para o rótulo através da propriedade KeyboardAcceleratorTextOverride dos MenuFlyoutItem, ToggleMenuFlyoutItem, AppBarButton e AppBarToggleButton (utilize um único espaço se não desejar texto).

Observação

O texto de substituição não será apresentado se o sistema não conseguir detetar um teclado associado (pode verificá-lo através da propriedade KeyboardPresent).

Conceitos Avançados

Aqui, analisamos alguns aspetos de baixo nível dos aceleradores de teclado.

Prioridade de eventos de entrada

Os eventos de entrada ocorrem numa sequência específica que pode intercetar e gerir com base nos requisitos da sua aplicação.

O evento de borbulhas KeyDown/KeyUp

Em XAML, uma tecla é processada como se existisse apenas um pipeline de borbulhas de entrada. Esta canalização de entrada é utilizada pelos eventos KeyDown/KeyUp e pela entrada de caracteres. Por exemplo, se um elemento tiver foco e o utilizador pressionar uma tecla, um evento KeyDown é gerado no elemento, seguido pelo pai do elemento, e assim sucessivamente na árvore, até que a propriedade args.Handled seja verdadeira.

O evento KeyDown também é utilizado por alguns controlos para implementar os aceleradores de controlo integrados. Quando um controlo tem uma tecla de atalho, gere o evento KeyDown, o que significa que não haverá propagação do evento KeyDown. Por exemplo, o RichEditBox suporta cópia com Ctrl+C. Quando Ctrl é pressionado, o evento KeyDown é disparado e surge, mas quando o utilizador pressiona C ao mesmo tempo, o evento KeyDown é marcado como Handled e não é levantado (a menos que o parâmetro handledEventsToo do UIElement.AddHandler esteja definido como true).

O evento CharacterReceived

Como o evento CharacterReceived é disparado após o evento KeyDown para controlos de texto como o TextBox, pode cancelar a entrada de caracteres no handler de eventos KeyDown.

Os eventos PreviewKeyDown e PreviewKeyUp

Os eventos de entrada de prévia são disparados antes de quaisquer outros eventos. Se não lidares com estes eventos, o acelerador do elemento que tem o foco é disparado, seguido pelo evento KeyDown. Ambos os eventos propagam-se até serem tratados.

Diagrama mostrando a sequência de eventos-chave Sequência de eventos-chave

Ordem dos acontecimentos:

Prévia de eventos KeyDown

Acelerador de aplicações
Método OnKeyDown
Evento KeyDown
Aceleradores de aplicações no pai
Método OnKeyDown no pai
Evento KeyDown no evento principal
(Bolhas até à raiz)

Evento CharacterReceived
Eventos PreviewKeyUp
KeyUpEvents

Quando o evento acelerador é tratado, o evento KeyDown também é marcado como tratado. O evento KeyUp permanece sem tratamento.

Resolução de aceleradores

Um evento de atalho de teclado propaga-se desde o elemento que tem foco até a raiz. Se o evento não for tratado, o framework XAML procura outros aceleradores de aplicações não delimitados fora do caminho de propagação.

Quando dois aceleradores de teclado são definidos com a mesma combinação de teclas, é invocado o primeiro acelerador de teclado encontrado na árvore visual.

Aceleradores de teclado com escopo são invocados apenas quando o foco está dentro de um escopo específico. Por exemplo, numa grelha que contém dezenas de controlos, um acelerador de teclado pode ser invocado para um controlo apenas quando o foco está dentro da grelha (o dono do âmbito).

Delimitação de aceleradores de forma programática

O método UIElement.TryInvokeKeyboardAccelerator invoca quaisquer aceleradores correspondentes na subárvore do elemento.

O método UIElement.OnProcessKeyboardAccelerators é executado antes do acelerador do teclado. Este método passa um objeto ProcessKeyboardAcceleratorArgs que contém a tecla, o modificador e um Booleano que indica se o acelerador do teclado é manipulado. Se marcado como tratado, o acelerador do teclado faz bolhas (por isso o acelerador exterior do teclado nunca é invocado).

Observação

O OnProcessKeyboardAccelerators dispara sempre, seja manipulado ou não (semelhante ao evento OnKeyDown). Você deve verificar se o evento foi marcado como resolvido.

Neste exemplo, usamos OnProcessKeyboardAccelerators e TryInvokeKeyboardAccelerator para definir aceleradores de teclado ao objeto Página:

protected override void OnProcessKeyboardAccelerators(
  ProcessKeyboardAcceleratorArgs args)
{
  if(args.Handled != true)
  {
    this.TryInvokeKeyboardAccelerator(args);
    args.Handled = true;
  }
}

Localizar os aceleradores

Recomendamos localizar todos os aceleradores de teclado. Podes fazer isto com o ficheiro de recursos padrão (.resw) e o atributo x:Uid nas tuas declarações XAML. Neste exemplo, o Windows Runtime carrega automaticamente os recursos.

Diagrama da localização do acelerador de teclado com o ficheiro de recursos Localização do acelerador de teclado com o ficheiro de recursos

<Button x:Uid="myButton" Click="OnSave">
  <Button.KeyboardAccelerators>
    <KeyboardAccelerator x:Uid="myKeyAccelerator" Modifiers="Control"/>
  </Button.KeyboardAccelerators>
</Button>

Observação

Os aceleradores de teclado são implementados como teclas virtuais. Aceleradores localizados devem ser escolhidos a partir da coleção pré-definida de códigosVirtual-Key (caso contrário, ocorrerá um erro no parser XAML).

Configurar um acelerador programaticamente

Aqui está um exemplo de definição programática de um acelerador:

void AddAccelerator(
  VirtualKeyModifiers keyModifiers, 
  VirtualKey key, 
  TypedEventHandler<KeyboardAccelerator, KeyboardAcceleratorInvokedEventArgs> handler )
  {
    var accelerator = 
      new KeyboardAccelerator() 
      { 
        Modifiers = keyModifiers, Key = key
      };
    accelerator.Invoked += handler;
    this.KeyboardAccelerators.Add(accelerator);
  }

Observação

O KeyboardAccelerator não é partilhável, o mesmo KeyboardAccelerator não pode ser adicionado a vários elementos.

Substituir o comportamento do acelerador do teclado

Podes gerir o evento KeyboardAccelerator.Invoked para sobrepor o comportamento padrão do KeyboardAccelerator.

Este exemplo mostra como sobrescrever o comando "Selecionar todos" (Ctrl+A acelerador de teclado) num controlo personalizado do ListView. Também definimos a propriedade Handled como true para evitar que o evento se propague ainda mais.

public class MyListView : ListView
{
  …
  protected override void OnKeyboardAcceleratorInvoked(KeyboardAcceleratorInvokedEventArgs args) 
  {
    if(args.Accelerator.Key == VirtualKey.A 
      && args.Accelerator.Modifiers == KeyboardModifiers.Control)
    {
      CustomSelectAll(TypeOfSelection.OnlyNumbers); 
      args.Handled = true;
    }
  }
  …
}

Samples