Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Eventos de teclado e foco
Os seguintes eventos de teclado podem ocorrer para teclados de hardware e de toque.
| Event | Description |
|---|---|
| KeyDown | Ocorre quando uma tecla é pressionada. |
| Chaveamento | Ocorre quando uma chave é liberada. |
Importante
Alguns controles XAML manipulam eventos de entrada internamente. Nesses casos, pode parecer que um evento de entrada não ocorre porque o ouvinte de eventos não invoca o manipulador associado. Normalmente, esse subconjunto de teclas é processado pelo manipulador de classe para fornecer suporte interno à acessibilidade básica do teclado. Por exemplo, a classe Button substitui os eventos OnKeyDown para a tecla Space e a tecla Enter (bem como OnPointerPressed) e os roteia para o evento Click do controle. Quando um pressionamento de tecla é manipulado pela classe de controle, os eventos KeyDown e KeyUp não são gerados.
Isso fornece um equivalente de teclado interno para invocar o botão, semelhante a tocá-lo com um dedo ou clicar nele com um mouse. Chaves diferentes de Space ou Enter ainda disparam eventos KeyDown e KeyUp . Para saber mais sobre como funciona a manipulação de eventos baseada em classe (especificamente, a seção "Manipuladores de eventos de entrada em controles"), veja Visão geral de eventos e eventos roteados.
Os controles em sua interface do usuário geram eventos de teclado somente quando eles têm foco de entrada. Um controle individual ganha foco quando o usuário clica ou toca diretamente nesse controle no layout, ou usa a tecla Tab para entrar em uma sequência de guias dentro da área de conteúdo.
Você também pode chamar o método Focus de um controle para forçar o foco. Isso é necessário quando você implementa teclas de atalho, porque o foco do teclado não é definido por padrão quando a interface do usuário é carregada. Para obter mais informações, consulte o Exemplo de teclas de atalho mais adiante neste tópico.
Para que um controle receba o foco de entrada, ele deve estar habilitado, visível e ter valores de propriedade IsTabStop e HitTestVisible de true. Este é o estado padrão para a maioria dos controles. Quando um controle tem foco de entrada, ele pode gerar e responder a eventos de entrada do teclado, conforme descrito posteriormente neste tópico. Você também pode responder a um controle que está recebendo ou perdendo o foco manipulando os eventos GotFocus e LostFocus .
Por padrão, a sequência de guias de controles é a ordem em que eles aparecem na Extensible Application Markup Language (XAML). No entanto, você pode modificar essa ordem usando a propriedade TabIndex . Para saber mais, veja Implementando a acessibilidade do teclado.
Manipuladores de eventos de teclado
Um manipulador de eventos de entrada implementa um delegado que fornece as seguintes informações:
- O remetente do evento. O remetente relata o objeto onde o manipulador de eventos está anexado.
- Dados do evento. Para eventos de teclado, esses dados serão uma instância de KeyRoutedEventArgs. O delegado para manipuladores é KeyEventHandler. As propriedades mais relevantes de KeyRoutedEventArgs para a maioria dos cenários de manipulador são Key e possivelmente KeyStatus.
- OriginalSource. Como os eventos de teclado são eventos roteados, os dados do evento fornecem OriginalSource. Se você deliberadamente permitir que eventos borbulhem através de uma árvore de objetos, OriginalSource às vezes é o objeto de preocupação em vez do emissor. No entanto, isso depende do seu design. Para obter mais informações sobre como você pode usar OriginalSource em vez de remetente, consulte a seção "Eventos roteados pelo teclado" deste tópico ou Visão geral de eventos e eventos roteados.
Anexando um manipulador de eventos de teclado
Você pode anexar funções de manipulador de eventos de teclado para qualquer objeto que inclua o evento como membro. Isso inclui qualquer classe derivada de UIElement . O exemplo XAML a seguir mostra como anexar manipuladores para o evento KeyUp para um Grid.
<Grid KeyUp="Grid_KeyUp">
...
</Grid>
Você também pode anexar um manipulador de eventos no código. Para obter mais informações, consulte Visão geral de eventos e eventos roteados.
Definindo um manipulador de eventos de teclado
O exemplo a seguir mostra a definição de manipulador de eventos incompleta para o manipulador de eventos KeyUp que foi anexado no exemplo anterior.
void Grid_KeyUp(object sender, KeyRoutedEventArgs e)
{
//handling code here
}
Private Sub Grid_KeyUp(ByVal sender As Object, ByVal e As KeyRoutedEventArgs)
' handling code here
End Sub
void MyProject::MainPage::Grid_KeyUp(
Platform::Object^ sender,
Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
//handling code here
}
Usando KeyRoutedEventArgs
Todos os eventos de teclado usam KeyRoutedEventArgs para dados de eventos e KeyRoutedEventArgs contém as seguintes propriedades:
- Chave
- Estado-chave
- Manuseado
- OriginalSource (herdado de RoutedEventArgs)
Chaves virtuais
O evento KeyDown é gerado se uma tecla for pressionada. Da mesma forma, KeyUp é gerado se uma tecla for solta. Normalmente, você ouve os eventos para processar um valor de chave específico. Para determinar qual tecla é pressionada ou liberada, verifique o valor Key nos dados do evento. Key retorna um valor VirtualKey . A enumeração VirtualKey inclui todas as chaves suportadas.
Teclas modificadoras
As teclas modificadoras são teclas como Ctrl ou Shift que os utilizadores normalmente pressionam em combinação com outras teclas. Seu aplicativo pode usar essas combinações como atalhos de teclado personalizados para invocar comandos do aplicativo.
Observação
Para obter atalhos de teclado incorporados, consulte Teclas de acesso e Aceleradores de teclado.
Você pode detetar combinações de teclas de atalho nos manipuladores de eventos KeyDown e KeyUp . Quando ocorre um evento de teclado para uma tecla não modificadora, você pode verificar se uma tecla modificadora está no estado pressionado.
Como alternativa, a função GetKeyState() do CoreWindow (obtida por meio de CoreWindow.GetForCurrentThread()) também pode ser usada para verificar o estado do modificador quando uma tecla não modificadora é pressionada.
Os exemplos a seguir implementam esse segundo método, incluindo também o código stub para a primeira implementação.
Observação
A tecla Alt é representada pelo valor VirtualKey.Menu .
Exemplo de teclas de atalho
O exemplo a seguir demonstra como implementar um conjunto de teclas de atalho personalizadas. Neste exemplo, os usuários podem controlar a reprodução de mídia usando os botões Reproduzir, Pausar e Parar ou os atalhos de teclado Ctrl+P, Ctrl+A e Ctrl+S. O botão XAML mostra os atalhos usando dicas de ferramenta e as propriedades AutomationProperties nos rótulos dos botões. Essa autodocumentação é importante para aumentar a usabilidade e a acessibilidade do seu aplicativo. Para saber mais, veja Acessibilidade do teclado.
Observe também que a página define o foco de entrada para si mesma quando é carregada. Sem essa etapa, nenhum controle tem foco de entrada inicial e o aplicativo não gera eventos de entrada até que o usuário defina o foco de entrada manualmente (por exemplo, tabulando ou clicando em um controle).
<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>
//showing implementations but not header definitions
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
(void) e; // Unused parameter
this->Loaded+=ref new RoutedEventHandler(this,&MainPage::ProgrammaticFocus);
}
void MainPage::ProgrammaticFocus(Object^ sender, RoutedEventArgs^ e)
{
this->Focus(Windows::UI::Xaml::FocusState::Programmatic);
}
void KeyboardSupport::MainPage::MediaButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
FrameworkElement^ fe = safe_cast<FrameworkElement^>(sender);
if (fe->Name == "PlayButton") {DemoMovie->Play();}
if (fe->Name == "PauseButton") {DemoMovie->Pause();}
if (fe->Name == "StopButton") {DemoMovie->Stop();}
}
bool KeyboardSupport::MainPage::IsCtrlKeyPressed()
{
auto ctrlState = CoreWindow::GetForCurrentThread()->GetKeyState(VirtualKey::Control);
return (ctrlState & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down;
}
void KeyboardSupport::MainPage::Grid_KeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
if (e->Key == VirtualKey::Control) isCtrlKeyPressed = true;
}
void KeyboardSupport::MainPage::Grid_KeyUp(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
if (IsCtrlKeyPressed())
{
if (e->Key==VirtualKey::P) { DemoMovie->Play(); }
if (e->Key==VirtualKey::A) { DemoMovie->Pause(); }
if (e->Key==VirtualKey::S) { DemoMovie->Stop(); }
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// Set the input focus to ensure that keyboard events are raised.
this.Loaded += delegate { this.Focus(FocusState.Programmatic); };
}
private void MediaButton_Click(object sender, RoutedEventArgs e)
{
switch ((sender as Button).Name)
{
case "PlayButton": DemoMovie.Play(); break;
case "PauseButton": DemoMovie.Pause(); break;
case "StopButton": DemoMovie.Stop(); break;
}
}
private static bool IsCtrlKeyPressed()
{
var ctrlState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Control);
return (ctrlState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
}
private void Grid_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (IsCtrlKeyPressed())
{
switch (e.Key)
{
case VirtualKey.P: DemoMovie.Play(); break;
case VirtualKey.A: DemoMovie.Pause(); break;
case VirtualKey.S: DemoMovie.Stop(); break;
}
}
}
Private isCtrlKeyPressed As Boolean
Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
End Sub
Private Function IsCtrlKeyPressed As Boolean
Dim ctrlState As CoreVirtualKeyStates = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Control);
Return (ctrlState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
End Function
Private Sub Grid_KeyDown(sender As Object, e As KeyRoutedEventArgs)
If IsCtrlKeyPressed() Then
Select Case e.Key
Case Windows.System.VirtualKey.P
DemoMovie.Play()
Case Windows.System.VirtualKey.A
DemoMovie.Pause()
Case Windows.System.VirtualKey.S
DemoMovie.Stop()
End Select
End If
End Sub
Private Sub MediaButton_Click(sender As Object, e As RoutedEventArgs)
Dim fe As FrameworkElement = CType(sender, FrameworkElement)
Select Case fe.Name
Case "PlayButton"
DemoMovie.Play()
Case "PauseButton"
DemoMovie.Pause()
Case "StopButton"
DemoMovie.Stop()
End Select
End Sub
Observação
Definir AutomationProperties.AcceleratorKey ou AutomationProperties.AccessKey em XAML fornece informações de cadeia de caracteres, que documentam a tecla de atalho para invocar essa ação específica. As informações são capturadas por clientes de automação da interface do usuário da Microsoft, como o Narrador, e normalmente são fornecidas diretamente ao usuário.
Definir AutomationProperties.AcceleratorKey ou AutomationProperties.AccessKey não tem nenhuma ação por si só. Você ainda precisará anexar manipuladores para eventos KeyDown ou KeyUp para realmente implementar o comportamento de atalho de teclado em seu aplicativo. Além disso, a decoração de texto sublinhado para uma chave de acesso não é fornecida automaticamente. Você deve sublinhar explicitamente o texto para a chave específica em seu mnemônico como formatação de sublinhado embutido se desejar mostrar texto sublinhado na interface do usuário.
Eventos roteados pelo teclado
Certos eventos são eventos roteados, incluindo KeyDown e KeyUp. Os eventos roteados usam a estratégia de roteamento borbulhante. A estratégia de roteamento borbulhante significa que um evento se origina de um objeto filho e, em seguida, é roteado para objetos pai sucessivos na árvore de objetos. Isso representa outra oportunidade de manipular o mesmo evento e interagir com os mesmos dados de evento.
Considere o exemplo XAML a seguir, que manipula eventos KeyUp para um Canvas e dois objetos Button . Nesse caso, se você soltar uma tecla enquanto o foco é mantido por qualquer objeto Button , ele gera o evento KeyUp . O evento é então propagado até ao Canvas pai.
<StackPanel KeyUp="StackPanel_KeyUp">
<Button Name="ButtonA" Content="Button A"/>
<Button Name="ButtonB" Content="Button B"/>
<TextBlock Name="statusTextBlock"/>
</StackPanel>
O exemplo a seguir mostra como implementar o manipulador de eventos KeyUp para o conteúdo XAML correspondente no exemplo anterior.
void StackPanel_KeyUp(object sender, KeyRoutedEventArgs e)
{
statusTextBlock.Text = String.Format(
"The key {0} was pressed while focus was on {1}",
e.Key.ToString(), (e.OriginalSource as FrameworkElement).Name);
}
Observe o uso da propriedade OriginalSource no manipulador anterior. Aqui, OriginalSource relata o objeto que gerou o evento. O objeto não pôde ser o StackPanel porque o StackPanel não é um controle e não pode ter foco. Apenas um dos dois botões dentro do StackPanel poderia ter levantado o evento, mas qual? Use OriginalSource para distinguir o objeto de origem do evento real, se estiver manipulando o evento em um objeto pai.
A propriedade "Handled" nos dados do evento
Dependendo da sua estratégia de manipulação de eventos, talvez você queira que apenas um manipulador de eventos reaja a um evento borbulhante. Por exemplo, se você tiver um manipulador KeyUp específico anexado a um dos controles Button , ele terá a primeira oportunidade de manipular esse evento. Nesse caso, talvez você não queira que o painel pai também manipule o evento. Para esse cenário, você pode usar a propriedade Handled nos dados do evento.
A finalidade da propriedade Handled em uma classe de dados de evento roteado é relatar que outro manipulador registrado anteriormente na rota de evento já atuou. Isso influencia o comportamento do sistema de eventos encaminhados. Quando você define Handled como true em um manipulador de eventos, esse evento interrompe o roteamento e não é enviado para elementos pai sucessivos.
AddHandler e eventos de teclado já tratados
Você pode usar uma técnica especial para anexar manipuladores que podem agir em eventos que você já marcou como manipulados. Essa técnica usa o método AddHandler para registrar um manipulador, em vez de usar atributos XAML ou sintaxe específica da linguagem para adicionar manipuladores, como += em C#.
Uma limitação geral dessa técnica é que a API AddHandler usa um parâmetro do tipo RoutedEvent identificando o evento roteado em questão. Nem todos os eventos roteados fornecem um identificador RoutedEvent e, portanto, essa consideração afeta quais eventos roteados ainda podem ser manipulados no caso Handled . Os eventos KeyDown e KeyUp têm identificadores de eventos roteados (KeyDownEvent e KeyUpEvent) no UIElement. No entanto, outros eventos, como TextBox.TextChanged , não têm identificadores de evento roteados e, portanto, não podem ser usados com a técnica AddHandler .
Sobrescrevendo eventos e comportamento do teclado
Você pode substituir eventos-chave para controles específicos (como GridView) para fornecer navegação de foco consistente para vários dispositivos de entrada, incluindo teclado e gamepad.
No exemplo a seguir, subclassificamos o controle e substituímos o comportamento KeyDown para mover o foco para o conteúdo GridView quando qualquer tecla de seta é pressionada.
public class CustomGridView : GridView
{
protected override void OnKeyDown(KeyRoutedEventArgs e)
{
// Override arrow key behaviors.
if (e.Key != Windows.System.VirtualKey.Left && e.Key !=
Windows.System.VirtualKey.Right && e.Key !=
Windows.System.VirtualKey.Down && e.Key !=
Windows.System.VirtualKey.Up)
base.OnKeyDown(e);
else
FocusManager.TryMoveFocus(FocusNavigationDirection.Down);
}
}
Observação
Se estiver usando um GridView apenas para layout, considere usar outros controles, como ItemsControl com ItemsWrapGrid.
Comando
Um pequeno número de elementos da interface do usuário fornece suporte interno para comando. O comando usa eventos roteados relacionados à entrada em sua implementação subjacente. Ele permite o processamento de entrada de interface do usuário relacionada, como uma determinada ação de ponteiro ou uma chave aceleradora específica, invocando um único manipulador de comando.
Se o comando estiver disponível para um elemento da interface do usuário, considere usar suas APIs de comando em vez de quaisquer eventos de entrada discretos. Para obter mais informações, consulte ButtonBase.Command.
Você também pode implementar ICommand para encapsular a funcionalidade de comando que você invoca de manipuladores de eventos comuns. Isso permite que você use o comando mesmo quando não há nenhuma propriedade Command disponível.
Entrada de texto e controles
Alguns controlos reagem a eventos do teclado com o seu próprio manuseamento. Por exemplo, TextBox é um controle projetado para capturar e, em seguida, representar visualmente o texto que foi inserido usando o teclado. Ele usa KeyUp e KeyDown em sua própria lógica para capturar pressionamentos de teclas e, em seguida, também gera seu próprio evento TextChanged se o texto realmente mudou.
Você ainda pode geralmente adicionar manipuladores para KeyUp e KeyDown para um TextBox, ou qualquer controle relacionado que se destina a processar a entrada de texto. No entanto, como parte de seu design pretendido, um controle pode não responder a todos os valores-chave que são direcionados a ele por meio de eventos-chave. O comportamento é específico para cada controle.
Como exemplo, ButtonBase (a classe base para Button) processa KeyUp para que ele possa verificar a barra de espaço ou a tecla Enter. ButtonBase considera KeyUp equivalente ao botão esquerdo do rato pressionado com o objetivo de gerar um evento Click. Esse processamento do evento é realizado quando ButtonBase substitui o método virtual OnKeyUp. Em sua implementação, ele define Handled como true. O resultado é que qualquer pai de um botão que esteja escutando um evento chave, no caso de uma Barra de espaço, não receberia o evento já manipulado para seus próprios manipuladores.
Outro exemplo é TextBox. Algumas teclas, como as teclas de seta, não são consideradas texto por TextBox e, em vez disso, são consideradas específicas para o comportamento da interface do usuário de controle. O TextBox marca esses casos de evento como tratados.
Os controles personalizados podem implementar seu próprio comportamento de substituição semelhante para eventos-chave substituindo OnKeyDown / OnKeyUp. Se o seu controlo personalizado processa teclas aceleradoras específicas, ou tem um comportamento de controlo ou foco semelhante ao cenário descrito para TextBox, deve colocar essa lógica nos seus próprios OnKeyDown / OnKeyUp overrides.
O teclado tátil
Os controles de entrada de texto fornecem suporte automático para o teclado virtual. Quando o usuário define o foco de entrada para um controle de texto usando a entrada por toque, o teclado virtual aparece automaticamente. Quando o foco de entrada não está em um controle de texto, o teclado virtual fica oculto.
Quando o teclado virtual aparece, ele reposiciona automaticamente a interface do usuário para garantir que o elemento focado permaneça visível. Isso pode fazer com que outras áreas importantes da interface do usuário saiam da tela. No entanto, você pode desativar o comportamento padrão e fazer seus próprios ajustes de interface do usuário quando o teclado virtual aparecer. Para mais informações, consulte o Exemplo de teclado tátil.
Se você criar um controle personalizado que requer entrada de texto, mas não deriva de um controle de entrada de texto padrão, você pode adicionar suporte de teclado virtual implementando os padrões de controle de automação da interface do usuário corretos. Para mais informações, consulte o Exemplo de teclado tátil.
As teclas pressionadas no teclado virtual geram os eventos KeyDown e KeyUp, assim como nos teclados físicos. No entanto, o teclado virtual não gerará eventos de entrada para Ctrl+A, Ctrl+Z, Ctrl+X, Ctrl+C e Ctrl+V, que são reservados para manipulação de texto no controle de entrada.
Você pode tornar muito mais rápido e fácil para os usuários inserir dados em seu aplicativo definindo o escopo de entrada do controle de texto para corresponder ao tipo de dados que você espera que o usuário insira. O escopo de entrada fornece uma dica sobre o tipo de entrada de texto esperado pelo controle para que o sistema possa fornecer um layout de teclado virtual especializado para o tipo de entrada. Por exemplo, se uma caixa de texto for usada apenas para inserir um PIN de 4 dígitos, defina a propriedade InputScope como Number. Isso diz ao sistema para mostrar o layout do teclado numérico, o que torna mais fácil para o usuário inserir o PIN. Para obter mais detalhes, consulte Usar o escopo de entrada para alterar o teclado tátil.
Artigos relacionados
Developers
Projetistas
Samples
- Exemplo de teclado tátil
- Amostra de entrada básica
- Amostra de entrada de baixa latência
- Exemplo de visuais do Focus
Arquivar amostras
Windows developer