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

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

 

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

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

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

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

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

2) KeyDown和KeyPress在MSDN上的解釋徹底同樣,都是在按下鍵的時候發生,那區別是什麼呢?orm

[csharp] view plain copy print ?
  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。htm

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

 

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

KeyPressEventArgs裏自只定義了個KeyChar,而且是char型的。所以:three

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

 

[csharp] view plain copy print ?
  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 plain copy print ?
  1. private void textBox1_KeyPress(object sender, KeyPressEventArgs e)  
  2. {  
  3.     if (e.KeyChar >= '0' && e.KeyChar <= '9')  
  4.     {  
  5.     }  
  6. }  


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

 

[csharp] view plain copy print ?
  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 plain copy print ?
  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 plain copy print ?
  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 plain copy print ?
  1. class TextBoxEx :System.Windows.Forms.TextBox  
  2. {  
  3.   
  4.     protected override bool IsInputKey(System.Windows.Forms.Keys keyData)  
  5.     {  
  6.         if (keyData == System.Windows.Forms.Keys.Tab)  
  7.         {  
  8.             return true;  
  9.         }  
  10.         return base.IsInputKey(keyData);  
  11.     }  
  12. }  

 

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


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

相關文章
相關標籤/搜索