2011-05-03 96 views

回答

54
  • KeyDown:當人按下某個鍵時(當鍵盤首次檢測到某個鍵上的手指時,這發生在鍵被按下時)。

  • KeyPress:當一個鍵被按下然後釋放時發生。

  • KEYUP:發生在當鍵被釋放

你是正確的,當一個鍵被按下,然後鬆開,在我上述順序所有這些事件的發生。

+2

即使reggie沒有問這個問題,我在下面添加了一個關於什麼時候使用KeyDown和KeyUp的想法。 – 2013-03-01 23:11:52

+3

'KeyPress'描述是錯誤的。按下鍵時出現KeyPress,即使永不釋放。參見[科迪格雷的答案](http://stackoverflow.com/a/5871430/1219414)。 – Juan 2015-05-31 20:49:33

63

嗯,我不知道你仔細檢查了MSDN documentation。它規定的順序三個事件發生相當明確:

重要事件出現以下順序:

  1. 的KeyDown
  2. 按鍵響應
  3. KEYUP

當用戶按下鍵盤上的某個鍵時,立即產生KeyDown,而它們是s直到堅持下來。

KeyPress升高爲字符鍵(不同於KeyDown和KEYUP,這也被升高爲非字符鍵),而鍵被按下。這是比KeyDown或KeyUp更高級的事件,因此EventArgs中提供了不同的數據。

KeyUp在用戶釋放鍵盤上的某個鍵後產生。

通常,您應該在應用程序中處理KeyUp事件。直到用戶釋放密鑰後之後,操作才能在用戶界面中啓動。而且由於KeyUp是一個比KeyPress更低級別的事件,所以您總是可以在觸手可及的情況下獲得大量關於被按下的鍵的信息,甚至可以用於處理非字符鍵。


事情需要注意所有這些事件,但是,它們只能由具有焦點的控件引發。這意味着如果表單上的按鈕控件目前擁有焦點,那麼您的表單的任何關鍵事件都不會得到提升。對於新來的.NET程序員來說,這經常令人困惑。處理這種情況最好的辦法是通過重寫形式的ProcessCmdKey method

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
{ 
    if (keyData == (Keys.Control | Keys.A)) 
    { 
     MessageBox.Show("You pressed Ctrl+A!"); 
    } 
} 
+0

我不知道這個信息有多容易找到?在我看來,如果有一個圖表顯示每個本地Windows控件的事件發生順序,那麼這將對您有所幫助... – 2012-07-18 19:59:21

+0

或者某種信息聚合網站可以用問答形式輕鬆表示信息無障礙?去原始文件並不總是理想的解決方案... – weberc2 2012-10-12 12:33:00

+0

@Clay他們沒有這樣的圖表,因爲事件/消息的順序(一般來說)隨時都可能發生變化。它是底層控制的實現細節,因此您不能依賴特定的* all *可用消息的順序。但是,一些特定的消息總是以特定的順序發送,僅僅是因爲它們的設計及其含義。例如,我在這裏發出的那些。我想,WinForms文檔對關鍵相關事件有很好的解釋。 – 2013-05-22 07:23:53

2

KeyDown然後KeyPress然後KeyUp是我找到的順序。

通常,當您想要鎖定KeyDown的應用程序時,如果用戶在按住Shift鍵的同時按住多鍵輸入的按鍵並進行控制鍵模式修改。 KeyPress適用於簡單的鍵入類型邏輯 - 只需獲取按鍵。 KeyUp被掛鉤以便在執行其他處理KeyPress之後執行的邏輯,例如在主邏輯生效後KeyPress之後修改文本編輯框的內容。坦率地說,我沒有使用KeyUp那麼多,但有時它是在別的東西已經處理之後得到消息的唯一方法,您需要檢查/修復發生了什麼。

7

下面是當你不希望使用KEYUP情況:

你有一個列表框,按下一排回車鍵調用編輯器對話框。問題:如果用戶在編輯器的OK按鈕上按Enter鍵,則KeyUp(e.KeyCode = Enter)事件將泄漏回您的列表框,導致編輯器重新打開。如果用戶按下編輯器的「確定」按鈕上的空格鍵,則不會發生這種情況;在這種情況下,KeyUp(e.KeyCode = Space)事件在編輯器關閉之前由編輯器處理。

這裏有一個選擇啓發式我用:

If I'm handling the Enter key and I need to guard against a case like the one above 
    then I use KeyDown  
Else if I'm handling key combinations (e.g. CTRL+C) 
    then I favor* KeyDown (KeyUp can make these awkward) 
Else if I am allowing press & hold autorepeat 
    then I use KeyDown  
Else 
    I use KeyUp 

*如果這個動作是可以在常用的產品中做了一個,說微軟Office,如CTRL + A(對於「全選」 ),那麼我模仿微軟的行爲,因爲這是用戶習慣的。

+0

非常有幫助的想法吉姆。但是,這不會導致不一致的體驗嗎?這可能是不應該發生的,因爲對話不應該在關鍵事件之前採取行動。到目前爲止,我一直使用KeyUp(Enter鍵)來保持一致,但是我遇到了你的狀態問題。 – 2013-10-28 21:17:40

+0

在WPF中,可以通過預覽事件處理Enter鍵的「泄漏」,對嗎? – Sabuncu 2014-06-20 13:56:51