如何从DataGridView数据单元中获取按下按键的按键事件

问题描述:

我需要在控制单元编辑中的单元格编辑期间接收按键事件。如何从DataGridView数据单元中获取按下按键的按键事件

从我在网上发现的DataGridView被设计为将所有关键事件从DataGridView传递到单元格编辑控件,并且您无法轻松获取这些事件。

我发现这piece of code陷阱这些事件控制DataGrid,但这并不适用于DataGridView

终于想通了。 这个难题有两个部分 - 从单元格编辑控制中获取密钥并从DataGridView本身获取密钥。这是我的代码。要使用它,您只需订阅自定义事件:keyPressHook

class KeyPressAwareDataGridView : DataGridView 
{ 

    protected override void OnControlAdded(ControlEventArgs e) 
    { 
     this.subscribeEvents(e.Control); 
     base.OnControlAdded(e); 
    } 

    protected override void OnControlRemoved(ControlEventArgs e) 
    { 
     this.unsubscribeEvents(e.Control); 
     base.OnControlRemoved(e); 
    } 

    protected override bool ProcessDataGridViewKey(KeyEventArgs e) 
    { 
     bool procesedInternally = false; 

     if (this.keyPressHook != null) 
     { 
      this.keyPressHook(this, e); 
      procesedInternally = e.SuppressKeyPress; 
     } 

     if (procesedInternally) 
     { 
      return true; 
     } 
     else 
     { 
      return base.ProcessDataGridViewKey(e); 
     } 
    } 


    private void subscribeEvents(Control control) 
    { 
     control.KeyDown += new KeyEventHandler(this.control_KeyDown); 
     control.ControlAdded += new ControlEventHandler(this.control_ControlAdded); 
     control.ControlRemoved += new ControlEventHandler(this.control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      this.subscribeEvents(innerControl); 
     } 
    } 

    private void unsubscribeEvents(Control control) 
    { 
     control.KeyDown -= new KeyEventHandler(this.control_KeyDown); 
     control.ControlAdded -= new ControlEventHandler(this.control_ControlAdded); 
     control.ControlRemoved -= new ControlEventHandler(this.control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      this.unsubscribeEvents(innerControl); 
     } 
    } 

    private void control_ControlAdded(object sender, ControlEventArgs e) 
    { 
     this.subscribeEvents(e.Control); 
    } 

    private void control_ControlRemoved(object sender, ControlEventArgs e) 
    { 
     this.unsubscribeEvents(e.Control); 
    } 

    private void control_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (this.keyPressHook != null) 
     { 
      this.keyPressHook(this, e); 
     } 
    } 

    public event KeyEventHandler keyPressHook; 

} 
+0

您能否提供更多关于如何操作的信息? – eladyanai 2012-08-09 15:13:44

您必须重写DataGridViewCell/DataGridViewTextBoxCell/otherTypes并处理派生类中的键*事件。

也许不如Mladen Prajdic上面的答案那么好,但也许会更容易一些,具体取决于您的情况。您可以重写表单或控件本身的ProcessCmdKey方法,处理那里的按键,并检查当前单元格。

试试这个:

class KeyPressAwareDataGridView : DataGridView 
{ 
    protected override void OnControlAdded(ControlEventArgs e) 
    { 
     SubscribeEvents(e.Control); 
     base.OnControlAdded(e); 
    } 

    protected override void OnControlRemoved(ControlEventArgs e) 
    { 
     UnsubscribeEvents(e.Control); 
     base.OnControlRemoved(e); 
    } 

    private void SubscribeEvents(Control control) 
    { 
     control.KeyPress += new KeyPressEventHandler(control_KeyPress); 
     control.ControlAdded += new ControlEventHandler(control_ControlAdded); 
     control.ControlRemoved += new ControlEventHandler(control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      SubscribeEvents(innerControl); 
     } 
    } 

    private void UnsubscribeEvents(Control control) 
    { 
     control.KeyPress -= new KeyPressEventHandler(control_KeyPress); 
     control.ControlAdded -= new ControlEventHandler(control_ControlAdded); 
     control.ControlRemoved -= new ControlEventHandler(control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      UnsubscribeEvents(innerControl); 
     } 
    } 

    private void control_ControlAdded(object sender, ControlEventArgs e) 
    { 
     SubscribeEvents(e.Control); 
    } 

    private void control_ControlRemoved(object sender, ControlEventArgs e) 
    { 
     UnsubscribeEvents(e.Control); 
    } 

    private void control_KeyPress(object sender, KeyPressEventArgs e) 
    { 
     // Apply your logic here whether this is the key pressed event you need. 
     // (e.g. "if(SelectedCells != null)") 
     MessageBox.Show(e.KeyChar.ToString()); 
    } 
} 

我找到了部分解决方案通过听EditingControlShowing并添加按键侦听器,每一个新的编辑控制。

这使我可以访问大多数的键,但我仍然没有得到箭头键。

我会试试Eren Aygunes的建议。

或者,对于那些不想为这样的occassions创建我们自己的DataGridView的用户;有这种方法(在C++中):它使用DataGridView的EditingControlShowing事件。

private: System::Boolean fIsNonNumeric; 
private: static System::Windows::Forms::KeyEventHandler^ EventKeyDown = nullptr; 
private: static System::Windows::Forms::KeyPressEventHandler^ EventKeyPress = nullptr; 
private: System::Void dataGridView_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) 
{ 
    fIsNonNumeric= false; 

    // Determine whether the keystroke is a number from the top of the keyboard. 
    if (e->KeyCode < Keys::D0 || e->KeyCode > Keys::D9) 
    { 
    // Determine whether the keystroke is a number from the keypad. 
    if (e->KeyCode < Keys::NumPad0 || e->KeyCode > Keys::NumPad9) 
    { 
     // Determine whether the keystroke is a backspace. 
     if (e->KeyCode != Keys::Back) 
     { 
     // A non-numerical keystroke was pressed. 
     // Set the flag to true and evaluate in KeyPress event. 
     fIsNonNumeric = true; 
     } 
    } 
    } 
} 

private: System::Void dataGridView_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e) 
{ 
    // Should we stop the character from being entered...? 
    if (fIsNonNumeric == true) 
    e->Handled = true; 
} 

private: System::Void dataGridView_Machines_EditingControlShowing(System::Object^ sender, System::Windows::Forms::DataGridViewEditingControlShowingEventArgs^ e) 
{ 
    if (nullptr == EventKeyDown) 
    EventKeyDown = (gcnew System::Windows::Forms::KeyEventHandler(this, &ProjectForm::dataGridView_KeyDown)); 

    if (nullptr == EventKeyPress) 
    EventKeyPress = (gcnew System::Windows::Forms::KeyPressEventHandler(this, &ProjectForm::dataGridView_KeyPress)); 

    e->Control->KeyDown -= EventKeyDown; 
    e->Control->KeyPress -= EventKeyPress; 

    e->Control->KeyDown += EventKeyDown; 
    e->Control->KeyPress += EventKeyPress; 
}