2010-11-26 47 views
17

當我編輯單元格內的文本時,DataGridView的keydown事件不起作用。DataGridView keydown事件不工作在C#

我指定快捷Alt + S鍵保存數據,它的工作原理時,細胞不處於編輯模式,但是如果是在下面的代碼編輯模式下無法正常工作

private void dataGridView1_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.KeyData == (Keys.Alt | Keys.S)) 
    { 
     //save data 
    } 
} 
+0

它沒有被觸發,或者代碼執行不正確?你能解釋一下你在做什麼嗎? – Rox 2010-11-26 10:23:35

+0

部分在這個鏈接的答案是有點相關 - http://stackoverflow.com/questions/686309/datagridview-change-edit-control-size-while-editing/23703744 – barlop 2016-05-29 03:50:29

回答

19

每當單元處於編輯模式,其託管的控件正在接收KeyDown事件,而不是包含它的父代DataGridView這就是您的鍵盤快捷鍵在單元格未處於編輯模式時(即使它被選中)正在工作的原因,因爲您的DataGridView控件本身會收到KeyDown事件。但是,當處於編輯模式時,單元格包含的編輯控件正在接收事件,並且沒有發生任何事情,因爲它沒有附加自定義處理程序例程。

我已經花了太多的時間調整的標準DataGridView控制處理編輯提交我想它的方式,我發現要解決這種現象的最簡單的方法是通過繼承已有的DataGridView控制和覆蓋其ProcessCmdKey function。無論您在此處輸入的自定義代碼是否在DataGridView頂部按下某個鍵時都會運行,而不管它是否處於編輯模式。

例如,你可以做這樣的事情:

class MyDataGridView : System.Windows.Forms.DataGridView 
{ 
    protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) 
    { 

     MessageBox.Show("Key Press Detected"); 

     if ((keyData == (Keys.Alt | Keys.S))) 
     { 
      //Save data 
     } 

     return base.ProcessCmdKey(ref msg, keyData); 
    } 
} 

另請參閱相關的,雖然有點老,文章:How to trap keystrokes in controls by using Visual C#

+0

好建議。 WM_KEYDOWN測試不是必須的順便說一句。 – 2010-11-26 15:42:10

+0

非常感謝,您的建議 – 2010-11-26 16:08:29

+0

@Hans Passant:我同意這不是必要的,我通常不會包含它。在我看到我所鏈接的文章將其推薦爲「良好實踐」後,我回過頭去添加它。 – 2010-11-26 23:39:59

13

做的另一種方法是使用EditingControlShowing事件重定向事件處理如下自定義事件處理程序:

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 
{ 
    if (e.Control is DataGridViewTextBoxEditingControl tb) 
      { 
       tb.KeyDown -= dataGridView1_KeyDown; 
       tb.KeyDown += dataGridView1_KeyDown; 
      } 
} 

//then in your keydown event handler, execute your code 
private void dataGridView1_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.KeyData == (Keys.Alt | Keys.S)) 
    { 
     //save data 
    } 
} 
-2

使用PreviewKeyDown事件

private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) 
{ 

} 
3

我只是嘗試了更簡單的方法如下:

  1. 設置窗體的KeyPreview屬性true
  2. 而不是在網格上捕獲KeyDown事件,捕獲窗體上的KeyDown事件。

如下代碼:

Private Sub form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown 

    If grd.Focused Then 

     'Do your work 

    End If 

End Sub 
1

這是事實,EditingControlShowing可以幫助,但如果你要趕上Enter鍵。在這種情況下,應該使用以下方法:

private void dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 
    { 
     if (e.Control is DataGridViewTextBoxEditingControl) 
     { 
      DataGridViewTextBoxEditingControl tb = e.Control as DataGridViewTextBoxEditingControl; 
      tb.KeyDown -= dataGridView_KeyDown; 
      tb.PreviewKeyDown -= dataGridView_PreviewKeyDown; 
      tb.KeyDown += dataGridView_KeyDown; 
      tb.PreviewKeyDown += dataGridView_PreviewKeyDown; 
     } 
    } 

    void dataGridView_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) 
    { 
     if (e.KeyData == Keys.Enter) 
     { 
      <your logic goes here> 
     } 
    }