I need to perform a task whenever the user ordinarily ends edit mode (no matter if the user actually modified the value or not; but not when the user cancels edit mode by pressing ESC) in a TextBox column of a DataGridView
control.
I tried several events of the DataGridView
control itself and also of the editing control, but none of them does exactly what I want:
DataGridView.CellValidating
and DataGridView.CellValidated
:
These events are fired whenever the user selects another cell, even if the cell was not in edit mode. I tried to check the IsCurrentCellDirty
property inside the CellValidating
event. This is almost what I need but IsCurrentCellDirty
is only set when the user actually changes the value. But I also need to perform the task when the user ordinarily ends edit mode without having changed anything. These events are not fired when the user cancels edit mode, which is good.
DataGridView.CellValueChanged
This event is also fired too often (it is also fired when the value of a cell is set programmatically).
DataGridView.CellEndEdit
This event is almost what I want. But it is also fired when the user cancels edit mode by pressing ESC. Is there a way to check if edit mode was cancelled inside the CellEndEdit
event?
DataGridView.CellParsing
This event is almost what I want. But it is not fired when the user ends edit mode without having changed anything.
Validating
and Validated
events of the editing control
I registered to these events inside the DataGridView.EditingControlShowing
event. They do almost what I want but they are also fired when the user cancels edit mode by pressing ESC. Is there a way to check if edit mode was cancelled inside the these events?
Any other suggestions for events I could register to and/or flags I could check to achieve the desired behaviour?
What you can do is register to the PreviewKeyDown
event of the EditingControl
inside the EditingControlShowing
event of the DataGridView
. From there it is possible to detect if escape was pressed within the editing control, and set a flag that will be read by the CellEndEdit
event.
You can infer the necessary events to register from the method names. This assumes you have a bool field within your class named escapePressed
which (not surprisingly) is the flag for escape being pressed.
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
e.Control.PreviewKeyDown -= Control_PreviewKeyDown; //avoid attaching multiple handlers in case control is cached
e.Control.PreviewKeyDown += new PreviewKeyDownEventHandler(Control_PreviewKeyDown);
}
void Control_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
Console.WriteLine("escape pressed");
escapePressed = true;
}
}
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (!escapePressed)
{
Console.WriteLine("do your stuff"); //escape was not pressed.
}
else escapePressed = false; //reset the flag
}