Событие нажатия клавиши DataGridView не работает в C#

Событие нажатия клавиш DataGridView не работает, когда я редактирую текст внутри ячейки.

Я назначаю сочетание клавиш Alt+S для сохранения данных, оно работает, когда ячейка не находится в режиме редактирования, но если она находится в режиме редактирования, приведенный ниже код не работает

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

7 ответов

Решение

Всякий раз, когда ячейка находится в режиме редактирования, ее размещенный элемент управления получает 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#

Еще один способ сделать это - использовать событие 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
    }
 }

Это правда, что 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>
        }
    }

Более простой способ, который я только что опробовал, заключается в следующем:

  1. Установить KeyPreview свойство формы для true,
  2. Вместо перехвата события KeyDown в Grid, перехватите событие 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

Класс решения 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);}}

Работал отлично для меня

я работал с этим

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

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

Использование PreviewKeyDown событие

private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{

}
Другие вопросы по тегам