El currentCellDirty es para que el evento también salte aunque no se haya cambiado de foco.
this.dataGridView1.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_OnCellValueChanged);
this.dataGridView1.CurrentCellDirtyStateChanged += new System.EventHandler(this.dataGridView1_CurrentCellDirtyStateChanged);
public void dataGridView1_CurrentCellDirtyStateChanged(object sender,EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
private void dataGridView1_OnCellValueChanged(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.EndEdit();
bla bla bla
}