2010-07-21 38 views
6

基本上,我有一個自定義控件的形式(沒有別的)。自定義控件完全是空的,並且窗體的KeyPreview設置爲true。箭頭沒有到達的關鍵事件

使用此設置,我沒有收到任何箭頭鍵或選項卡的KeyDown事件。我的鍵盤上的其他所有鍵都可以工作。我將KeyDown事件處理程序連接到所有發生此類事件的事件,所以我相信我不會錯過任何事情。

另外值得注意的是,如果我刪除(完全空的)自定義控件,我會得到箭頭鍵事件。

這到底是怎麼回事?

編輯:

我將此添加到窗體和控件,但我仍然沒有得到箭頭鍵:

protected override void WndProc(ref Message m) { 
    switch (m.Msg) { 
     case 0x100: //WM_KEYDOWN 
      //this is the control's version. In the form, it's this.Text 
      ParentForm.Text = ((Keys)m.WParam).ToString(); 
      break; 
    } 
    base.WndProc(ref m); 
} 

我還與間諜++檢查,並確定表單本身沒有得到任何WM_KEYDOWN消息,他們都去控制。但是,那就是說,控件是獲取箭頭鍵WM_KEYDOWN消息。嘆。

編輯2:我也更新了這個版本的ZIP文件。請看看吧,如果你想幫助...

編輯3:

我已經想通了這一點,排序的。表格正在吃箭頭鍵,可能是爲了保持孩子們的注意力。事實證明,如果表單是空的,我會得到事件。

無論如何,如果我這個代碼添加到形式,我開始再次得到事件:

public override bool PreProcessMessage(ref Message msg) { 
    switch (msg.Msg) { 
     case 0x100: //WM_KEYDOWN 
      return false; 
    } 
    return base.PreProcessMessage(ref msg); 
} 

當我重寫此,形式沒有得到一個機會來完成其骯髒的工作,等等我得到我的KeyDown事件。我認爲這樣做的一個副作用是我不能再使用我的鍵盤來瀏覽表單了(在這種情況下不是一個大問題,因爲它是一個遊戲,而且這個練習的整個目的是實現鍵盤導航!)

問題仍然是有關如何禁用這個「正常」,如果有一種方法...

+0

聽起來像你的用戶控件所在的窗體是捕獲事件並將其設置爲在你的UserControl接收之前進行處理。您是否確保在按下該按鍵時您的用戶控件具有焦點? – 2010-07-21 15:31:50

回答

10

我已經做了一些廣泛的測試,並且我已經想通了所有的東西。I wrote a blog post detailing the solution.

總之,你想覆蓋ProcessDialogKey方法形式:

protected override bool ProcessDialogKey(Keys keyData) { 
    return false; 
} 

這將導致箭頭鍵(和標籤)交付正常的KeyDown事件。然而!這也會導致正常的對話鍵功能(使用Tab導航控件等)失敗。如果你想保留這一點,但仍然得到KeyDown事件,而不是使用:

protected override bool ProcessDialogKey(Keys keyData) { 
    OnKeyDown(new KeyEventArgs(keyData)); 
    return base.ProcessDialogKey(keyData); 
} 

這將提供在keyDown消息,但是仍然有正常的對話導航。

+0

工程就像一個魅力。 – Carra 2011-05-12 16:22:35

+0

謝謝!完美的作品! – 2011-12-19 06:57:58

+0

你的博客鏈接已經死了?!? – 2014-12-20 19:59:10

0

如果重點是你的問題,你不能讓你的用戶的控制採取的焦點,並保持它,一個簡單的解決方案就是將事件回顯到您關心的關鍵事件的用戶控件上。訂閱您的表單keydown或按鍵事件,然後讓該事件向您的用戶控件發起事件。

因此,本質上,Form1_KeyPress將使用來自Form1_KeyPress的發件人和事件參數調用UserControl1_KeyPress。

protected void Form1_KeyPress(object sender, KeyEventArgs e) 
{ 
    UserControl1_KeyPress(sender, e); 
} 

否則,你可能不得不走冤枉路並重寫你的WndProc活動,得到你想要的功能。

+0

UserControl爲空,無法接收焦點(AFAIK)。所以,Form本身應該接收KeyDown事件。但事實並非如此。正如我在問題中所說的,我有事件處理程序連接到事件的所有事件,但沒有任何事件發生。 我可能會嘗試壓倒WndProc,但我真的不應該... – 2010-07-21 15:49:16

+0

我已經更新了OP,並使用了我的壓倒一切的結果WndProc – 2010-07-21 15:56:57