Share via

DataGridView _CurrentCellDirtyStateChanged not firing

john noble 241 Reputation points
2026-05-26T15:18:56.33+00:00

HI folks,

I have a datagridview with a _CurrentCellDirtyStateChanged event attached to it. Inside this event there is code that updates other values in another grid.

When the value of a cell is changed, by overtyping the value that is already there, it all works fine. But if I select the existing value and delete it, then type in a new value, the code does not enter the _CurrentCellDirtyStateChanged event because the IsCurrentCellDirty = false.

Hope this makes sense.

Can anyone advise on this ?

John

private void grdMaster_CurrentCellDirtyStateChanged(object sender, EventArgs e)

{

if (grdMaster.IsCurrentCellDirty) // always false after deleting the existing value and typing in new value

{

if (String.Compare(grdMaster.SelectedRows[0].Cells["totalTonnage"].FormattedValue.ToString(), "") == 0)

return;

int rowIndex = grdMaster.SelectedRows[0].Index;

if (grdMaster.Rows[rowIndex].Cells["totalfqaUnits"].Value is DBNull) return;

// decimal totalFQAs = Convert.ToDecimal(grdMaster.SelectedRows[0].Cells["totalFQAUnits"].FormattedValue);

decimal totalTonnage = Convert.ToDecimal(grdMaster.SelectedRows[0].Cells["totalTonnage"].FormattedValue);

// This fires the cell value changed handler below

grdMaster.CommitEdit(DataGridViewDataErrorContexts.Commit);

foreach(DataGridViewRow row in grdDetail.Rows)

{

// Update values in other grid

}

// This fires the cell value changed handler below

grdDetail.CommitEdit(DataGridViewDataErrorContexts.Commit);

}

}

Developer technologies | Visual Studio | Debugging
0 comments No comments

Answer accepted by question author

Sneha De 80 Reputation points
2026-05-26T17:31:59.14+00:00

private void grdMaster_CurrentCellDirtyStateChanged(object sender, EventArgs e)

{

if (grdMaster.IsCurrentCellDirty)

{

    grdMaster.CommitEdit(DataGridViewDataErrorContexts.Commit);

}

}

private void grdMaster_CellValueChanged(object sender, DataGridViewCellEventArgs e)

{

if (e.RowIndex < 0)

    return;

DataGridViewRow row = grdMaster.Rows[e.RowIndex];

object tonnageObj = row.Cells["totalTonnage"].Value;

if (tonnageObj == null || tonnageObj == DBNull.Value)

    return;

decimal totalTonnage;

if (!decimal.TryParse(tonnageObj.ToString(), out totalTonnage))

    return;

foreach (DataGridViewRow detailRow in grdDetail.Rows)

{

    // Update values in other grid

}

grdDetail.CommitEdit(DataGridViewDataErrorContexts.Commit);

}

Was this answer helpful?

1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. AI answer

    2026-05-26T15:19:13.11+00:00

    CurrentCellDirtyStateChanged is raised when the grid decides the current cell has become “dirty” (has uncommitted changes). The event itself does not depend on IsCurrentCellDirty being true; instead, IsCurrentCellDirty tells whether the grid currently considers the cell dirty at the time of the check.

    Key points from the DataGridView behavior:

    • A cell is marked dirty when its contents have changed but the change has not been committed. This is exposed via IsCurrentCellDirty.
    • The CurrentCellDirtyStateChanged event is what notifies that this dirty state has changed (from clean→dirty or dirty→clean).
    • Edits are typically committed when focus leaves the cell, or when CommitEdit/NotifyCurrentCellDirty is called.

    In the provided handler:

    void grdMaster_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        if (grdMaster.IsCurrentCellDirty)
        {
            // ... logic ...
            grdMaster.CommitEdit(DataGridViewDataErrorContexts.Commit);
            // ...
        }
    }
    

    If IsCurrentCellDirty is always false after deleting and retyping, then by the time the handler runs the grid is not treating the cell as dirty. The event still fires, but the if (grdMaster.IsCurrentCellDirty) condition prevents the code from running.

    To ensure the logic runs whenever the dirty state changes (including after delete/retype), remove or relax the IsCurrentCellDirty guard and, if needed, use it only to distinguish transitions:

    private void grdMaster_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        // Option A: always run when dirty state changes
        // If needed, check the column/row here instead of IsCurrentCellDirty
    
        if (grdMaster.IsCurrentCellDirty)
        {
            // Cell just became dirty – commit to raise CellValueChanged
            grdMaster.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }
    
        // Perform updates based on current cell value here
        // (do not rely on SelectedRows; use CurrentCell/RowIndex instead)
    }
    

    For custom editing controls or special scenarios where the grid does not automatically mark the cell as dirty, call NotifyCurrentCellDirty(true) from the editing control when its value changes. This explicitly tells the grid that the cell has uncommitted changes and will cause CurrentCellDirtyStateChanged to fire with IsCurrentCellDirty == true:

    protected override void OnValueChanged(EventArgs e)
    {
        valueChanged = true;
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnValueChanged(e);
    }
    

    If updates should occur after the value is committed rather than on every keystroke, move the update logic into the CellValueChanged event and use CurrentCellDirtyStateChanged only to force a commit for certain cell types (for example, check boxes) by calling CommitEdit(DataGridViewDataErrorContexts.Commit) when IsCurrentCellDirty is true.


    References:

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

    1 person found this answer helpful.

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.