The .NET DataGridView just doesn't seem quite to have the hook we need. The following gets pretty close:
1. Declare at the class level in the Form or UserControl that contains the grid:
Order mLastOrderAdded;
2. Handler for the BindingSource's AddingNew event:
void mOrdersBS_AddingNew(object sender, AddingNewEventArgs e) {
mLastOrderAdded = AddNewOrder();
e.NewObject = mLastOrderAdded;
}
3. Handler for the grid's KeyDown event:
void mOrdersDGV_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyValue == 27) {
//if (mOrdersDGV.CurrentRow.IsNewRow) {
//if (mOrdersDGV.CurrentRow.Index == mOrdersDGV.NewRowIndex - 1) {
if (mOrdersDGV.CurrentRow.DataBoundItem.Equals(mLastOrderAdded)) {
mLastOrderAdded.Delete();
}
}
}
This combination does the needful; unfortunately it will also delete the same row later if the user is (a) on that row, (b) presses ESC, and (c) no other row has been added since. Unfortunately, the NewItem row seems to become a non-NewItem row as soon as a created object is passed to it (as above in mOrdersBS_AddingNew() when the new Order is assigned to e.NewObject). So the IsNewRow test in the KeyDown handler (commented out) fails. If ESC was pressed on the row just added by clicking in the NewItem row, the test (mOrdersDGV.CurrentRow.Index == mOrdersDGV.NewRowIndex - 1; also commented out) succeeds, only because there's now a NewItem row with an index one higher than the one where the user is doing the editing. And that test can't distinguish between a last row just added using the NewItem row, and a last row that has been there for 20 minutes, with lots of editing going on in other rows, in between.
One piece of good news is that the code above doesn't cause deletion of the row containing the mLastOrderAdded if the user presses ESC while editing the value in a particular cell in that row. That press of ESC seems to get eaten in the process of undoing the cell edit, and doesn't trigger the DataGridView's KeyDown event.
By the way, I also explored the RowsRemoved, Validating, RowLeave, and CancelRowEdit events of the DataGridView, and the ListChanged event of the BindingSource that supplies the grid, without any success. It may simply be that the DataGridView is just a bit too DataSet- and DataTable-oriented to handle this particular occurrence well. Perhaps the DevExpress or Infragistics grid does a better job. Wish I had better news.