21

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

我正在分配快捷键Alt+S来保存数据,当单元格未处于编辑模式时它可以工作,但如果它处于编辑模式,则下面的代码不起作用

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

6 回答 6

25

每当单元格处于编辑模式时,它的托管控件都会接收事件,而不是包含它KeyDown的父控件。DataGridView这就是为什么只要单元格不处于编辑模式(即使它被选中),您的键盘快捷键就会起作用,因为您的DataGridView控件本身会接收KeyDown事件。但是,当您处于编辑模式时,单元格包含的编辑控件正在接收事件,并且没有任何反应,因为它没有附加您的自定义处理程序例程。

我花了太多时间来调整标准DataGridView控件以按我想要的方式处理编辑提交,我发现解决这种现象的最简单方法是对现有DataGridView控件进行子类化并覆盖其ProcessCmdKey功能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);
    }
}

另请参阅相关的(虽然有点旧)文章:如何使用 Visual C# 捕获控件中的击键

于 2010-11-26T11:59:31.030 回答
16

另一种方法是使用 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
    }
 }
于 2013-03-13T03:37:40.643 回答
7

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>
        }
    }
于 2015-05-19T13:35:31.940 回答
3

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

  1. KeyPreviewForm 的属性设置为true
  2. 不要在 Grid 上捕获 KeyDown 事件,而是在 Form 上捕获 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
于 2014-08-08T14:39:14.313 回答
0

我和这个一起工作

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

            private void grdViewOrderDetail_KeyDown(object sender, KeyEventArgs e)
              {
    
               //Code                     
              }
于 2021-03-05T14:30:26.783 回答
-4

使用PreviewKeyDown事件

private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{

}
于 2013-06-14T02:28:25.607 回答