Apa perbedaan antara KeyDown dan KeyPress di .NET?

185

Apa perbedaan antara acara KeyDowndan KeyPressacara .net?

Josh Kodroff
sumber

Jawaban:

308

Tampaknya ada banyak kesalahpahaman tentang ini!

Satu-satunya perbedaan praktis antara KeyDowndan KeyPressadalah KeyPressrelay karakter yang dihasilkan dari penekanan tombol, dan hanya dipanggil jika ada.

Dengan kata lain, jika Anda menekan Apada keyboard Anda, Anda akan mendapatkan urutan kejadian ini:

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

Tetapi jika Anda menekan Shift+ A, Anda akan mendapatkan:

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

Jika Anda menahan tombol untuk sementara waktu, Anda akan mendapatkan sesuatu seperti:

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

Perhatikan bahwa KeyPressterjadi di antara KeyDown dan KeyUp, bukan setelah KeyUp, seperti banyak jawaban lain telah menyatakan, itu KeyPresstidak disebut ketika karakter tidak dihasilkan, dan itu KeyDowndiulang ketika kunci ditekan, juga bertentangan dengan banyak jawaban lainnya .

Contoh kunci yang tidak secara langsung menghasilkan panggilan ke KeyPress:

  • Shift, Ctrl,Alt
  • F1 melalui F12
  • Tombol panah

Contoh kunci yang melakukan mengakibatkan panggilan ke KeyPress:

  • Amelalui Z, 0melalui 9, dll.
  • Spacebar
  • Tab (KeyChar = '\ t', ASCII 9)
  • Enter (KeyChar = '\ r', ASCII 13)
  • Esc (KeyChar = '\ x1b', ASCII 27)
  • Backspace (KeyChar = '\ b', ASCII 8)

Untuk yang penasaran, secara KeyDownkasar berkorelasi dengan WM_KEYDOWN, KeyPressuntuk WM_CHAR, dan KeyUpuntuk WM_KEYUP. WM_KEYDOWN dapat disebut lebih sedikit dari jumlah pengulangan kunci, tetapi mengirimkan jumlah pengulangan, yang, IIRC, menggunakan WinForms untuk menghasilkan tepat satu KeyDown per pengulangan.

P Ayah
sumber
2
Penjelasan yang sangat baik, thx, satu peringatan, Escape tidak memicu KeyPress di Chrome (tidak yakin tentang yang lain).
Barney
3
@BarnabasSzabolcs: Chrome menjalankan .NET?
P Daddy
@Paddy ups, saya telah mengabaikan, saya pikir itu javascript: D tetapi dengan gaya yang sedikit aneh: P bagaimanapun, tampaknya aturannya sangat mirip: DD ... cukup lucu jawaban ini membantu saya banyak pula .. Ceria :)
Barney
@PDaddy Saya tahu bahwa setidaknya Tab tidak mengaktifkan KeyDown atau KeyUp secara default
PsychoData
@ PsychoData: Itu karena tombol Tab mengubah fokus, sehingga tidak diproses sebagai input. Jika Anda menimpa ProcessDialogKeydan kembali palsu saat keyDataini Keys.Tabatau Keys.Shift | Keys.Tab, maka Anda akan melihat tombol Tab di (On) Key (Bawah | Tekan | Up).
P Ayah
73

Acara KeyPress tidak dimunculkan oleh tombol bukan karakter; Namun, kunci noncharacter meningkatkan peristiwa KeyDown dan KeyUp.

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

Jon Spokes
sumber
17
Sebagian besar jawaban lain salah dalam satu atau lain cara, tetapi yang ini paling dekat dengan kenyataan. KeyPress hanya dinaikkan untuk tombol karakter dan mematuhi pengaturan penundaan / pengulangan pengetikan keyboard. Urutan kejadian yang sebenarnya adalah: 1) KeyDown 2) untuk tombol karakter KeyPress satu atau lebih kali (tergantung pada pengaturan sistem dan berapa lama tombol disimpan) 3) KeyUp
Filip Navara
Saya tidak memiliki perwakilan untuk melakukannya, tetapi bisakah seseorang merusak wiki dan menggabungkan konten dari komentar di atas dan jawaban yang diterima?
Josh Kodroff
11
Komentar Filip Navara tidak sepenuhnya benar. Jika tombol ditekan, Anda akan mendapatkan KeyDown, KeyPress, KeyDown, KeyPress, KeyDown, KeyPress KeyUp. KeyDown dipanggil untuk setiap pengulangan.
P Ayah
9

KeyPress hanya diaktifkan oleh karakter yang dapat dicetak dan dipecat setelah acara KeyDown. Bergantung pada pengaturan penundaan pengetikan, mungkin ada beberapa acara KeyDown dan KeyPress tetapi hanya satu acara KeyUp.

KeyDown
KeyPress
KeyUp

stevehipwell
sumber
Anda dekat, tetapi tidak aktif tentang urutannya.
P Ayah
@ P Ayah - Saya sudah memperbaikinya, harus diperiksa ulang sebelum pergi dari memori.
stevehipwell
@ Stevo3000, fyi: karakter unicode yang tidak dapat dicetak juga akan menjalankan peristiwa KeyPress. Saya memiliki aplikasi yang membaca data yang disisipkan oleh pembaca barcode ke dalam kotak teks dan pembaca termasuk karakter unicode yang tidak dapat dicetak.
Jeff LaFay
@ jlafay - Tidak menurut MSDN Acara KeyPress tidak dimunculkan oleh kunci bukan karakter; Namun, kunci noncharacter meningkatkan peristiwa KeyDown dan KeyUp.
stevehipwell
@ Stevo3000, saya tidak yakin bagaimana pemindai barcode memasukkan teks ke dalam kotak teks tetapi KeyPress menyala untuk karakter khusus yang dikirimkannya. Nilai dimulai dengan karakter yang tidak dapat dicetak dan berakhir dengan karakter yang tidak dapat dicetak. Jadi saya tidak yakin bagaimana menembak jika itu benar. Mungkin saya akan melihat rakitan .Net yang berisi acara dengan IL Spy untuk mengetahui lebih baik apa yang sebenarnya terdeteksi.
Jeff LaFay
5

KeyPress adalah tingkat abstraksi yang lebih tinggi daripada KeyDown (dan KeyUp). KeyDown dan KeyUp terkait dengan perangkat keras: tindakan sebenarnya dari tombol pada keyboard. KeyPress lebih "Saya menerima karakter dari keyboard".

Jeff Hornby
sumber
4

Dari MSDN:

Peristiwa utama terjadi dalam urutan berikut:

  1. KeyDown

  2. Tekan tombol

  3. KeyUp

Selanjutnya, KeyPress memberi Anda kesempatan untuk menyatakan tindakan sebagai " ditangani " untuk mencegahnya melakukan apa pun.

Jon B
sumber
FYI, KeyDown dan KeyUp juga memiliki properti Handled yang dapat Anda atur sehingga bukan antara KeyPress dan acara utama lainnya.
Jeff LaFay
FWIW meskipun KeyUp, seperti KeyDown, mendapatkan parameter KeyEventArgs Handledpropertinya tidak beroperasi untuk KeyUp ( SuppressKeyPressjuga tidak beroperasi).
JonP
3

Keydown menekan tombol tanpa melepaskannya, Keypress adalah siklus tekan-dan-lepas yang lengkap.

Dengan kata lain, KeyDown + KeyUp = Keypress

Rob Cowell
sumber
3
menurut MSDN, urutan acara adalah KeyDown, KeyPress, KeyUp ( msdn.microsoft.com/en-us/library/… )
Nathan Koop
@RobCowell Juga, seperti yang ditunjukkan jlafay, KeyPress sama sekali tidak bergantung pada KeyDown atau KeyUp.
PsychoData
1

Dari Pengembang Blogging :

Untuk memahami perbedaan antara penekanan tombol dan penekanan tombol, penting untuk memahami perbedaan antara "karakter" dan "kunci" . Sebuah "kunci" adalah tombol fisik pada keyboard komputer sementara "karakter" adalah simbol diketik dengan menekan sebuah tombol. Secara teori, peristiwa keydown dan keyup mewakili tombol yang ditekan atau dilepaskan, sedangkan peristiwa penekanan tombol mewakili karakter yang sedang diketik. Implementasi teori tidak sama di semua browser.

Catatan: Anda juga dapat mencoba Key Event Tester (tersedia di situs yang disebutkan di atas) untuk memahami konsep ini.

Abdul Latheef Mohamed
sumber
1

KEYUP akan ditangkap hanya satu kali, setelah tombol dilepas, terlepas dari berapa lama tombol akan ditekan, jadi jika Anda ingin menangkap pers hanya sekali, KEYUP adalah acara yang cocok untuk ditangkap.

Michael Haephrati
sumber
The KeyPressevent yang dibangkitkan untuk setiap karakter yang dihasilkan dari input, baik dalam menanggapi penekanan tombol fisik maupun ketika karakter adalah hasil dari fitur autorepeat. Cara Input Keyboard Bekerja mendokumentasikan perilaku ini.
IInspectable
Kamu benar. Saya akan memperbarui jawaban saya. Jawaban yang benar adalah dengan menggunakan KEYUP yang akan dipicu sekali, setelah merilis satu atau lebih klik kunci.
Michael Haephrati
Meskipun tidak lagi salah, tetap saja tidak menjawab pertanyaan yang diajukan. Ini tidak berguna.
IInspectable
0

Penjelasan termudah:

Saya menekan tombol 'd' sebentar dan kemudian dirilis.

dddddd

peristiwa keydown terjadi satu kali sebelum d pertama muncul di layar, peristiwa penekanan tombol terjadi 6 kali dan peristiwa keyup terjadi setelah d terakhir muncul di layar.


sumber
sialan, salah membaca pertanyaan dan mendapatkannya di kepala saya dia maksud javascript