DataGridView Events

Robert Hegner picture Robert Hegner · Jan 9, 2012 · Viewed 11.2k times · Source

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?

Answer

Rotem picture Rotem · Jan 9, 2012

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
}