Qual é a diferença entre KeyDown e KeyPress no .NET?


185

Qual é a diferença entre the KeyDowne KeyPressevents in .net?

Respostas:


308

Aparentemente, há muito mal-entendido sobre isso!

A única diferença prática entre KeyDowne KeyPressé que KeyPressretransmite o caractere resultante de um pressionamento de tecla e é chamado apenas se houver um.

Em outras palavras, se você pressionar Ao teclado, receberá esta sequência de eventos:

  1. KeyDown: KeyCode = Keys.A, KeyData = Keys.A, Modificadores = Keys.None
  2. KeyPress: KeyChar = 'a'
  3. KeyUp: KeyCode = Keys.A

Mas se você pressionar Shift+ A, receberá:

  1. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modificadores = Keys.Shift
  2. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  3. KeyPress: KeyChar = 'A'
  4. KeyUp: KeyCode = Keys.A
  5. KeyUp: KeyCode = Keys.ShiftKey

Se você pressionar as teclas por um tempo, obterá algo como:

  1. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modificadores = Keys.Shift
  2. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modificadores = Keys.Shift
  3. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modificadores = Keys.Shift
  4. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modificadores = Keys.Shift
  5. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modificadores = Keys.Shift
  6. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  7. KeyPress: KeyChar = 'A'
  8. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  9. KeyPress: KeyChar = 'A'
  10. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  11. KeyPress: KeyChar = 'A'
  12. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  13. KeyPress: KeyChar = 'A'
  14. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  15. KeyPress: KeyChar = 'A'
  16. KeyUp: KeyCode = Keys.A
  17. KeyUp: KeyCode = Keys.ShiftKey

Observe que KeyPressocorre entre KeyDown e KeyUp, não depois KeyUp, como muitas das outras respostas têm afirmado, que KeyPressnão é chamado quando um personagem não é gerado, e que KeyDowné repetido enquanto a tecla é pressionada, também ao contrário de muitas das outras respostas .

Exemplos de chaves que não resultam diretamente em chamadas para KeyPress:

  • Shift, Ctrl,Alt
  • F1 através F12
  • Teclas de seta

Exemplos de chaves que fazer resultado em chamadas para KeyPress:

  • Aatravés Z, 0através 9, etc.
  • Spacebar
  • Tab (KeyChar = '\ t', ASCII 9)
  • Enter (KeyChar = '\ r', ASCII 13)
  • Esc (KeyChar = '\ x1b', ASCII 27)
  • Backspace (KeyChar = '\ b', ASCII 8)

Para os curiosos, KeyDownaproximadamente se correlaciona com WM_KEYDOWN, KeyPresspara WM_CHARe KeyUppara WM_KEYUP. WM_KEYDOWN pode ser chamado menos que o número de repetições de chave, mas envia uma contagem de repetições que, IIRC, o WinForms usa para gerar exatamente um KeyDown por repetição.


2
Excelente explicação, thx, uma ressalva, o Escape não aciona o KeyPress no Chrome (não tenho certeza sobre os outros).
Barney

3
@BarnabasSzabolcs: o Chrome executa o .NET?
P papai

@Paddy ups, eu tenho esquecido, eu pensei que era javascript: D, mas com um estilo um pouco estranho: P, no entanto, parece que as regras são bastante semelhantes: DD ... curiosamente, essa resposta me ajudou muito de qualquer maneira .. #
Barney #

@PDaddy Eu sei que pelo menos Tab doesnt fogo KeyDown ou KeyUp por padrão
PsychoData

@ PsychoData: Isso ocorre porque a tecla Tab altera o foco, por isso não é processada como entrada. Se você substituir ProcessDialogKeye retornar false quando keyDatafor Keys.Tabou Keys.Shift | Keys.Tab, verá a tecla Tab na tecla (On) (Down | Pressione | Up).
P papai

73

O evento KeyPress não é gerado por chaves que não sejam caracteres; no entanto, as chaves não características aumentam os eventos KeyDown e KeyUp.

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress.aspx


17
A maioria das outras respostas está errada de uma maneira ou de outra, mas essa se aproxima da realidade. KeyPress é gerado apenas para teclas de caracteres e obedece à configuração de atrasos / repetições de digitação do teclado. A seqüência real dos eventos é a seguinte: 1) KeyDown 2) para a chave caráter um KeyPress ou mais vezes (dependendo das configurações do sistema e quanto tempo a chave é realizada) 3) KeyUp
Filip Navara

Eu não tenho o representante para fazer isso, mas alguém poderia invadir um wiki e combinar o conteúdo do comentário acima e a resposta aceita?
Josh Kodroff

11
O comentário de Filip Navara não está totalmente correto. Se uma tecla for pressionada, você obterá KeyDown, KeyPress, KeyDown, KeyPress, KeyDown, KeyPress KeyUp. KeyDown é chamado para cada repetição.
P Daddy

9

O KeyPress é acionado apenas por caracteres imprimíveis e é acionado após o evento KeyDown. Dependendo das configurações de atraso na digitação, pode haver vários eventos KeyDown e KeyPress, mas apenas um evento KeyUp.

KeyDown
KeyPress
KeyUp


Você está perto, mas desconhece a sequência.
P Daddy

@ Paizinho P - eu corrigi, deveria ter verificado duas vezes antes de sair da memória.
stevehipwell

@ Stevo3000, fyi: caracteres unicode não imprimíveis também acionam eventos do KeyPress. Eu tenho um aplicativo que lê dados inseridos por um leitor de código de barras em uma caixa de texto e o leitor inclui caracteres unicode não imprimíveis.
Jeff LaFay

@jlafay - Não de acordo com o MSDN O evento KeyPress não é gerado por chaves que não sejam caracteres; no entanto, as chaves não características aumentam os eventos KeyDown e KeyUp.
Stevehipwell 11/02

@ Stevo3000, não tenho certeza de como o scanner de código de barras insere texto em uma caixa de texto, mas o KeyPress é acionado para caracteres especiais que ele envia. O valor começa com um caractere não imprimível e termina com um caractere não imprimível. Então, eu não tenho certeza de como está disparando, se isso é verdade. Talvez eu dê uma olhada no assembly .Net que contém os eventos com o IL Spy para ver melhor o que é realmente detectado.
11133 Jeff LaFay

5

KeyPress é um nível mais alto de abstração que KeyDown (e KeyUp). KeyDown e KeyUp estão relacionados ao hardware: a ação real de uma tecla no teclado. KeyPress é mais "recebi um caractere do teclado".


4

Do MSDN:

Os principais eventos ocorrem na seguinte ordem:

  1. KeyDown

  2. Pressione o botão

  3. KeyUp

Além disso, o KeyPress oferece a chance de declarar a ação como " manipulada " para impedir que ela faça qualquer coisa.


FYI, KeyDown e KeyUp também têm uma propriedade Handled que você pode definir para que não ocorra entre o KeyPress e os outros eventos-chave.
101313 Jeff LaFay

FWIW, embora KeyUp, como KeyDown, obtenha um parâmetro KeyEventArgs, sua Handledpropriedade é inoperante para KeyUp ( SuppressKeyPresstambém é inoperante).
21816 JonP,


3

Keydown está pressionando a tecla sem soltá-la; Keypress é um ciclo completo de pressionar e soltar.

Em outras palavras, KeyDown + KeyUp = Keypress


3
de acordo com MSDN, a sequência de eventos é KeyDown, KeyPress, KeyUp ( msdn.microsoft.com/en-us/library/... )
Nathan Koop

@RobCowell Além disso, como jlafay apontou, o KeyPress não depende totalmente do KeyDown ou do KeyUp.
precisa

1

Do desenvolvedor de blogs :

Para entender a diferença entre pressionamento de tecla e pressionamento de tecla, é útil entender a diferença entre um "caractere" e uma "tecla" . Uma "tecla" é um botão físico no teclado do computador, enquanto um "caractere" é um símbolo digitado ao pressionar um botão. Em teoria, os eventos keydown e keyup representam teclas pressionadas ou liberadas, enquanto o evento keypress representa um caractere sendo digitado. A implementação da teoria não é a mesma em todos os navegadores.

Nota: Você também pode experimentar o Key Event Tester (disponível no site mencionado acima) para entender esse conceito.


1

A KEYUP será capturada apenas uma vez, após soltar a tecla pressionada, independentemente de quanto tempo a tecla será mantida pressionada; portanto, se você deseja capturar essa tecla apenas uma vez, KEYUP é o evento adequado para capturar.


O KeyPressevento é gerado para cada caractere gerado a partir da entrada, tanto em resposta a pressionamentos de teclas físicos quanto quando o caractere é o resultado do recurso de repetição automática. Como funciona a entrada do teclado documenta esse comportamento.
11nspectable

Você está certo. Vou atualizar minha resposta. A resposta correta é usar KEYUP, que será acionado uma vez, após o lançamento de uma ou mais teclas pressionadas.
Michael Haephrati

Embora não esteja mais errado, ainda não responde à pergunta que foi feita. Isso não é útil.
11nspectable

0

Explicação mais fácil:

Eu segurei a tecla 'd' por um segundo e depois soltei.

dddddd

o evento de pressionamento de tecla ocorreu uma vez antes do primeiro d aparecer na tela, o evento de pressionamento de tecla ocorreu 6 vezes e o evento de pressionamento de tecla ocorreu após o último d aparecer na tela.


caramba, descaracterizou a pergunta e tenho isso na minha cabeça que ele quis dizer javascript
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.