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
A simpler way I just tried out is as follows:
KeyPreview
property of the Form to true
.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
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#
use PreviewKeyDown
event
private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
}
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
}
}
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>
}
}