C# DataGridView按键关闭事件在C中不起作用#

C# DataGridView按键关闭事件在C中不起作用#,c#,.net,winforms,datagridview,keydown,C#,.net,Winforms,Datagridview,Keydown,当我在单元格内编辑文本时,DataGridView keydown事件不起作用 我正在指定快捷方式Alt+S来保存数据,当单元格未处于编辑模式时,快捷方式有效,但如果单元格处于编辑模式,则代码无效 private void dataGridView1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyData == (Keys.Alt | Keys.S)) { //save data } } 每当单

当我在单元格内编辑文本时,DataGridView keydown事件不起作用

我正在指定快捷方式Alt+S来保存数据,当单元格未处于编辑模式时,快捷方式有效,但如果单元格处于编辑模式,则代码无效

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

每当单元格处于编辑模式时,其宿主控件都会接收到
KeyDown
事件,而不是包含该事件的父级
DataGridView
这就是为什么每当单元格未处于编辑模式时(即使已选中),键盘快捷键都会工作的原因,因为
DataGridView
控件本身接收
KeyDown
事件。但是,当您处于编辑模式时,单元格包含的编辑控件正在接收事件,并且不会发生任何事情,因为它没有附加自定义处理程序例程

我花了太多时间调整标准的
DataGridView
控件,以按我希望的方式处理编辑提交,我发现避免这种现象的最简单方法是对现有的
DataGridView
控件进行子类化,并覆盖其。无论您在这里输入什么自定义代码,只要按下
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);
    }
}

另请参阅相关的文章,尽管有点旧:

另一种方法是使用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
    }
 }

使用PreviewKeyDown事件

private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{

}

我刚才尝试过的一种更简单的方法如下:

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

   If grd.Focused Then

      'Do your work

   End If

End Sub
  • 将表单的
    KeyPreview
    属性设置为
    true
  • 与其在网格上捕捉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
    

    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>
            }
        }
    
    private void dataGridView\u EditingControlShowing(对象发送方,DataGridViewEditingControlShowingEventArgs e)
    {
    如果(例如,控件是DataGridViewTextBoxedEdit控件)
    {
    DataGridViewTextBoxEditingControl tb=e.控件作为DataGridViewTextBoxEditingControl;
    tb.KeyDown-=dataGridView\u KeyDown;
    tb.PreviewKeyDown-=dataGridView\u PreviewKeyDown;
    tb.KeyDown+=dataGridView\u KeyDown;
    tb.PreviewKeyDown+=dataGridView\u PreviewKeyDown;
    }
    }
    void dataGridView_PreviewKeyDown(对象发送方,PreviewKeyDownEventArgs e)
    {
    如果(e.KeyData==Keys.Enter)
    {
    }
    }
    
    我用过这个

                private void grdViewOrderDetail_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
                  {
                    grdViewOrderDetail_KeyDown(null,null);
                  }
    
                private void grdViewOrderDetail_KeyDown(object sender, KeyEventArgs e)
                  {
        
                   //Code                     
                  }
    

    它没有被触发,或者代码没有正确执行?你能多解释一下你的想法吗;你在做什么?这个链接的部分答案有点相关-好的建议。顺便说一句,WM_键控测试不是必需的。非常感谢您的支持advice@Hans帕桑:我同意这是没有必要的,而且我通常从不包括在内。当我看到我链接到的文章推荐它为“良好实践”后,我又重新添加了它。典型的KB措辞。在你测试它之前,你不会知道它的BS。目前为止命中率为0%。假设您有一个表单,其中a)datagridview的子类,b)一个文本框。您希望文本框中的值在按下键后显示在编辑的单元格中。。你知道怎么做吗?+1:这是我最好的方法,因为我不想对我的DataGridView进行子类化。我不清楚为什么“-=”,我还将上面的内容转换为VB.net:
    private sub dgvGrid1_editing(发件人作为对象,e作为DataGridViewediting控件显示事件参数)Handles dgvGrid1.EditingControls显示e.控件的类型是否为DataGridViewTextBoxEditingControl,然后将tb设置为DataGridViewTextBoxEditingControl=e.控件添加Handler tb.Keydown,dgvGrid1的地址\u Keydown End if End Sub
    谢谢。更简单:-)非常简单,尤其是我的整个表单是DataGridView。这不适用于字母数字键。它仍然进入编辑控件。