DataGridView keydown事件无法在C#中工作

Jav*_*ram 19 .net c# datagridview keydown winforms

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

我正在分配快捷键Alt + S来保存数据,它在单元格不处于编辑模式时有效,但如果它处于编辑模式,则代码不能正常工作

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

Cod*_*ray 22

每当单元格处于编辑模式时,其托管控件就会接收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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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


小智 15

另一种方法是使用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
    }
 }
Run Code Online (Sandbox Code Playgroud)

  • +1:这对我来说是最好的方式,因为我不想继承我的DataGridView. (2认同)

Asa*_*saf 6

确实 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>
        }
    }
Run Code Online (Sandbox Code Playgroud)