As teclas de seta para cima, para baixo, esquerda e direita não acionam o evento KeyDown

Eu estou construindo uma aplicação onde todas as principais inputs devem ser manipuladas pelo próprio windows.

Eu defini tabstop para false para cada controle que poderia pegar o foco exceto um painel (mas eu não sei se ele tem efeito).

Eu defino KeyPreview para true e estou manipulando o evento KeyDown neste formulário.

Meu problema é que às vezes a tecla de seta não responde mais:

  • O evento keydown não é triggersdo quando pressiono apenas uma tecla de seta.

  • O evento keydown é acionado se eu pressionar uma tecla de seta com o modificador de controle.

Você tem uma idéia de por que minha tecla de seta parou de triggersr um evento?

protected override bool IsInputKey(Keys keyData) { switch (keyData) { case Keys.Right: case Keys.Left: case Keys.Up: case Keys.Down: return true; case Keys.Shift | Keys.Right: case Keys.Shift | Keys.Left: case Keys.Shift | Keys.Up: case Keys.Shift | Keys.Down: return true; } return base.IsInputKey(keyData); } protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); switch (e.KeyCode) { case Keys.Left: case Keys.Right: case Keys.Up: case Keys.Down: if (e.Shift) { } else { } break; } } 

Eu estava tendo exatamente o mesmo problema. Eu considerei a resposta fornecida pelo @Snarfblam; no entanto, se você ler a documentação no MSDN, o método ProcessCMDKey destina-se a replace os principais events para itens de menu em um aplicativo.

Eu recentemente deparei com este artigo da Microsoft, que parece bastante promissor: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx . Segundo a Microsoft, a melhor coisa a fazer é definir e.IsInputKey=true; no evento PreviewKeyDown depois de detectar as teclas de seta. Isso irá triggersr o evento KeyDown .

Isso funcionou muito bem para mim e foi menos hacker do que sobrepujar a ProcessCMDKey.

Estou usando o PreviewKeyDown

  private void _calendar_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e){ switch (e.KeyCode){ case Keys.Down: case Keys.Right: //action break; case Keys.Up: case Keys.Left: //action break; } } 

Veja a resposta de Rodolfo Neuber para a melhor resposta


(Minha resposta original):

Derive de uma class de controle e você pode replace o método ProcessCmdKey. A Microsoft optou por omitir essas chaves dos events KeyDown porque elas afetam vários controles e movem o foco, mas isso torna muito difícil fazer com que um aplicativo reaja a essas chaves de qualquer outra forma.

Infelizmente, é muito difícil conseguir isso com as teclas de seta, devido a restrições nos events KeyDown. No entanto, existem algumas maneiras de contornar isso:

  • Como o @Snarfblam afirmou, você pode replace o método ProcessCmdKey , que retém a capacidade de analisar pressionamentos de teclas de seta.
  • Como a resposta aceita desta questão afirma, o XNA tem um método embutido chamado Keyboard.GetState () , que permite usar inputs de tecla de seta. No entanto, o WinForms não tem isso, mas isso pode ser feito através de um P / Invoke , ou usando uma class que ajude com isso .

Eu recomendo tentar usar essa class. É bem simples fazer isso:

 var left = KeyboardInfo.GetKeyState(Keys.Left); var right = KeyboardInfo.GetKeyState(Keys.Right); var up = KeyboardInfo.GetKeyState(Keys.Up); var down = KeyboardInfo.GetKeyState(Keys.Down); if (left.IsPressed) { //do something... } //etc... 

Se você usar isso em combinação com o evento KeyDown, acredito que você possa atingir sua meta com segurança.

Eu tive um problema semelhante ao chamar a janela do WPF fora do WinForms.

 var wpfwindow = new ScreenBoardWPF.IzbiraProjekti(); ElementHost.EnableModelessKeyboardInterop(wpfwindow); wpfwindow.Show(); 

No entanto, mostrando janela como um diálogo , funcionou

 var wpfwindow = new ScreenBoardWPF.IzbiraProjekti(); ElementHost.EnableModelessKeyboardInterop(wpfwindow); wpfwindow.ShowDialog(); 

Espero que isto ajude.

Para capturar pressionamentos de tecla em um controle de formulários, você deve derivar uma nova class é baseada na class do controle que você deseja e você replace o ProcessCmdKey ().

 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { //handle your keys here } 

Exemplo:

 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { //capture up arrow key if (keyData == Keys.Up ) { MessageBox.Show("You pressed Up arrow key"); return true; } return base.ProcessCmdKey(ref msg, keyData); } 

Full source … Teclas de seta em c #

Vayne

A melhor maneira de fazer, eu acho, é lidar com isso como o MSDN disse em http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx

Mas aguente, como você realmente precisa. Meu caminho (no exemplo abaixo) é pegar todos os KeyDown 😉

  ///  /// onPreviewKeyDown ///  ///  protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e) { e.IsInputKey = true; } ///  /// onKeyDown ///  ///  protected override void OnKeyDown(KeyEventArgs e) { Input.SetFlag(e.KeyCode); e.Handled = true; } ///  /// onKeyUp ///  ///  protected override void OnKeyUp(KeyEventArgs e) { Input.RemoveFlag(e.KeyCode); e.Handled = true; } 

Eu tive o mesmo problema e já estava usando o código na resposta selecionada. esse link foi a resposta para mim; talvez para os outros também.

Como desativar a navegação no WinForm com setas em c #?