DataGridView keydown 事件在 C# 中不起作用

发布于 2024-10-04 17:04:40 字数 307 浏览 8 评论 0原文

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

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

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

DataGridView keydown event is not working when I am editing text inside a cell.

I am assigning shortcut Alt+S to save the data, it works when cell is not in edit mode, but if it is in edit mode below code is not working

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

删除会话 2024-10-11 17:04:40

只要单元格处于编辑模式,其托管控件就会接收 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# 进行控制

Whenever a cell is in edit mode, its hosted control is receiving the KeyDown event instead of the parent DataGridView that contains it. That's why your keyboard shortcut is working whenever a cell is not in edit mode (even if it is selected), because your DataGridView control itself receives the KeyDown event. However, when you are in edit mode, the edit control contained by the cell is receiving the event, and nothing happens because it doesn't have your custom handler routine attached to it.

I have spent way too much time tweaking the standard DataGridView control to handle edit commits the way I want it to, and I found that the easiest way to get around this phenomenon is by subclassing the existing DataGridView control and overriding its ProcessCmdKey function. Whatever custom code that you put in here will run whenever a key is pressed on top of the DataGridView, regardless of whether or not it is in edit mode.

For example, you could do something like this:

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);
    }
}

Also see related, though somewhat older, article: How to trap keystrokes in controls by using Visual C#

蓝天 2024-10-11 17:04:40

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

Another way of doing it is by using the EditingControlShowing event to redirect the event handling to a custom event handler as below:

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
    }
 }
风透绣罗衣 2024-10-11 17:04:40

确实,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>
        }
    }

This is true that EditingControlShowing can help, but not if you wants to catch the Enter key. In that case, one should use the following method:

 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>
        }
    }
江湖彼岸 2024-10-11 17:04:40

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

  1. 将Form的KeyPreview属性设置为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

A simpler way I just tried out is as follows:

  1. Set the KeyPreview property of the Form to true.
  2. Instead of catching the KeyDown event on Grid, catch the KeyDown event on Form.

Code as follows:

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

   If grd.Focused Then

      'Do your work

   End If

End Sub
蹲在坟头点根烟 2024-10-11 17:04:40

我用这个工作过

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

            private void grdViewOrderDetail_KeyDown(object sender, KeyEventArgs e)
              {
    
               //Code                     
              }

I worked with this

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

            private void grdViewOrderDetail_KeyDown(object sender, KeyEventArgs e)
              {
    
               //Code                     
              }
你另情深 2024-10-11 17:04:40

解决方案
类 MyDataGridView : System.Windows.Forms.DataGridView {
protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) {
if ( keyData == Keys.Enter ) {

处理输入键

}
返回base.ProcessCmdKey(ref msg, keyData);
}
很好

对我来说效果

The solution
class MyDataGridView : System.Windows.Forms.DataGridView {
protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) {
if ( keyData == Keys.Enter ) {
.
Process Enter Key
.
}
return base.ProcessCmdKey(ref msg, keyData);
}
}

Worked perfectly for me

缱倦旧时光 2024-10-11 17:04:40

使用 PreviewKeyDown 事件

private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{

}

use PreviewKeyDown event

private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文