1. 程式人生 > >Winform下KeyDown,KeyPress,KeyUp事件的總結(轉)

Winform下KeyDown,KeyPress,KeyUp事件的總結(轉)

convert from keyevent 代碼 .com edit capi add div

原文: http://www.cnblogs.com/xiashengwang/archive/2011/09/15/2578798.html

在winform程序中,經常會用到這幾個事件用於控制數字輸入,按鍵動作等操作,但一直沒有完全弄清楚他們之間的區別和聯系,到底什麽時候用哪一個事件合適,閑暇無事,做了一個小小的總結,以免以後犯糊塗。

1) 這三個事件調用的先後順序(MSDN)

1. KeyDown :在控件有焦點的情況下按下鍵時發生

2. KeyPress :在控件有焦點的情況下按下鍵時發生。

3. KeyUp :在控件有焦點的情況下釋放鍵時發生。

2) KeyDown和KeyPress在MSDN上的解釋完全一樣,都是在按下鍵的時候發生,那區別是什麽呢?

[csharp] view plaincopyprint?
  1. textBox1_KeyDown(object sender, KeyEventArgs e)
  2. textBox1_KeyPress(object sender, KeyPressEventArgs e)
  3. textBox1_KeyUp(object sender, KeyEventArgs e)

從時間函數傳入的事件參數可以看出,KeyDown和KeyUp用的是KeyEventArgs,KeyPress 用的是KeyPressEventArgs。

查閱MSDN,KeyEventArgs 提供了KeyCode,KeyData等System.Windows.Forms.Keys裏定義的枚舉。如下:

[csharp] view plaincopyprint?
  1. using System;
  2. using System.ComponentModel;
  3. using System.Drawing.Design;
  4. using System.Runtime.InteropServices;
  5. namespace System.Windows.Forms
  6. {
  7. // 概要:
  8. // Specifies key codes and modifiers.
  9. [Flags]
  10. [ComVisible(true)]
  11. [TypeConverter(typeof(KeysConverter))]
  12. [Editor("System.Windows.Forms.Design.ShortcutKeysEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
  13. public enum Keys
  14. {
  15. // 概要:
  16. // The bitmask to extract modifiers from a key value.
  17. Modifiers = -65536,
  18. //
  19. // 概要:
  20. // No key pressed.
  21. None = 0,
  22. //
  23. // 概要:
  24. // The left mouse button.
  25. LButton = 1,
  26. //
  27. // 概要:
  28. // The right mouse button.
  29. RButton = 2,
  30. //
  31. // 概要:
  32. // The CANCEL key.
  33. Cancel = 3,
  34. //
  35. // 概要:
  36. // The middle mouse button (three-button mouse).
  37. MButton = 4,
  38. //
  39. // 概要:
  40. // The first x mouse button (five-button mouse).
  41. XButton1 = 5,
  42. //
  43. // 概要:
  44. // The second x mouse button (five-button mouse).
  45. XButton2 = 6,
  46. //
  47. // 概要:
  48. // The BACKSPACE key.
  49. Back = 8,
  50. //
  51. // 概要:
  52. // The TAB key.
  53. Tab = 9,
  54. //
  55. // 概要:
  56. // The LINEFEED key.
  57. LineFeed = 10,
  58. //
  59. // 概要:
  60. // The CAPS LOCK key.
  61. Capital = 20,
  62. //內容太多了,略去。。。。。。
  63. // 概要:
  64. // The ALT modifier key.
  65. Alt = 262144,
  66. }
  67. }

KeyPressEventArgs裏自只定義了個KeyChar,並且是char型的。因此:

----要處理與按鍵相關的操作只能在KeyDown裏處理,如是否按了Ctrl鍵或是同時按下了Ctrl+A鍵,諸如此類的按鍵判斷都應該在KeyDown裏處理。(KeyUp也能獲得按鍵信息,不過是在按鍵上升是觸發)

[csharp] view plaincopyprint?
  1. private void textBox1_KeyDown(object sender, KeyEventArgs e)
  2. {
  3. //是否安了鍵盤的A鍵
  4. if (e.KeyCode == Keys.A)
  5. {
  6. }
  7. }

----要處理具體按下後的輸出字符要用KeyPresss事件,比如驗證是不是輸入了數字,判斷Ascii碼即可。

[csharp] view plaincopyprint?
  1. private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
  2. {
  3. if (e.KeyChar >= ‘0‘ && e.KeyChar <= ‘9‘)
  4. {
  5. }
  6. }


在KeyDown裏可以判斷是不是按了數字鍵來判斷,但是要同時判斷鍵盤上的數字和小鍵盤的數字,不太可取。

[csharp] view plaincopyprint?
  1. private void textBox1_KeyDown(object sender, KeyEventArgs e)
  2. {
  3. if((e.KeyCode >= Keys.D0 && e.KeyCode <=Keys.D9) ||
  4. (e.KeyCode>= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9))
  5. {
  6. }
  7. }


3)取消用戶輸入應該用什麽方法?

不要用戶輸入數字以外的字符,已經輸入的字符如何取消呢?答案是可以在KeyPress裏取消,也可以在KeyDown裏取消。

1, KeyPress裏取消輸入 (A不能輸入)

[csharp] view plaincopyprint?
  1. private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
  2. {
  3. if (e.KeyChar == ‘A‘)
  4. {
  5. e.Handled = true;
  6. }
  7. }

2,KeyDown裏取消輸入 (A不能輸入)

[csharp] view plaincopyprint?
  1. private void textBox1_KeyDown(object sender, KeyEventArgs e)
  2. {
  3. if (e.KeyCode == Keys.A)
  4. {
  5. e.SuppressKeyPress();
  6. }
  7. }

SuppressKeyPress方法可以取消KeyPress事件,註意此時KeyUp事件也被取消了(實驗得知)。

4)關於KeyDown和KeyUp

KeyDown觸發幾次KeyUp就觸發幾次。

1,按鍵盤的A鍵,KeyDwon和KeyUp各觸發一次。

KeyDown裏的KeyEventArgs的值如下:(註意:KeyCode,Keydata,KeyValue裏的值是偽代碼,不一定和程序吻合,只是為了說明問題)

KeyCode:Keys.A

KeyData:Keys.A

KeyValue:65

KeyUp裏的KeyEventArgs的值和KeyDown相同。

2,按鍵盤的Ctrl+A,KeyDwon和KeyUp個觸發兩次。

第一次KeyDown裏的KeyEventArgs的值如下:

KeyCode:Keys.ContrlKey

KeyData:Keys.ContrlKey

KeyValue:17

第二次KeyDown裏的KeyEventArgs的值如下:

KeyCode:Keys.A

KeyData:Keys.ContrlKey + Keys.A

KeyValue:65

第一次KeyUp裏的KeyEventArgs的值如下:

KeyCode:Keys.A

KeyData:Keys.ContrlKey + Keys.A

KeyValue:65

第二次KeyUp裏的KeyEventArgs的值如下:

KeyCode:Keys.ContrlKey

KeyData:Keys.ContrlKey

KeyValue:17

可以看出,KeyUp的順序和KeyDown順序是相反的,類似於棧,先進後出。

5) 某些特殊鍵在控件上被默認處理的解決辦法

比如,TextBox上的TAB鍵就被默認處理的,在TextBox上按Tab鍵,將不會觸發KeyDown已經後面的KeyPress和KeyUp事件,解決的辦法是重新TextBox控件的IsInputKey方法,這個在MSDN上有說明,特實踐證明了下,確實可行。

[csharp] view plaincopyprint?
  1. class TextBoxEx :System.Windows.Forms.TextBox
  2. {
  3. protected override bool IsInputKey(System.Windows.Forms.Keys keyData)
  4. {
  5. if (keyData == System.Windows.Forms.Keys.Tab)
  6. {
  7. return true;
  8. }
  9. return base.IsInputKey(keyData);
  10. }
  11. }

換用以上的TextBoxEx後,按下Tab鍵,就能觸發KeyDown,KeyPress,KeyUp等事件了。


以上純屬個人無事消遣,各位看官笑過就好。

Winform下KeyDown,KeyPress,KeyUp事件的總結(轉)