Событие нажатия клавиши 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>
}
}
Более простой способ, который я только что опробовал, заключается в следующем:
- Установить
KeyPreview
свойство формы дляtrue
, - Вместо перехвата события 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)
{
}