Cancelling adding a new item shown in a Windows Froms modal dialog

Cancelling adding a new item shown in a Windows Froms modal dialog

Old forum URL: forums.lhotka.net/forums/t/7756.aspx


nwatk posted on Friday, October 09, 2009

We are using csla 3.7.something and are trying to use Windows Forms data binding with a master window bound to a business object (Part) showing a child list of that business object (Volume Prices) in a grid with new/edit/delete buttons that bring up a modal dialog that also uses data binding.

The Volume Price modal edit dialog's binding properly reverts the changes from an edit when you cancel, but how do we revert the Add when you cancel adding a new one?

Previously we would do this:

private void btnAdd_Click(object sender, EventArgs e) {
part.BeginEdit();
PartVolumePrice price = part.VolumePrices.Add();
using (FormPartVolumePriceDialog frm = new FormPartVolumePriceDialog(price)) {
if (frm.ShowDialog() == DialogResult.OK) {
part.ApplyEdit();
} else {
part.CancelEdit();
}
}
}

But I get the impression from trying, and from http://forums.lhotka.net/forums/permalink/15741/15741/ShowThread.aspx#15741 that my code shouldn't be calling BeginEdit()/ApplyEdit()/CancelEdit() unless I DisableIEditableObject = true in my business object, and thus I handle this entirely myself.

now the best thing I can think of is having my Cancel case do part.VolumePrices.Remove(price), but I hesitate and ask because:
1) Not everywhere will the people with add privileges also have delete privileges
2) I have to be careful to not introduce cases where editing a child edits the parent, for example a "total quantity" property in the parent that is a sum of the children must be updated on all the strange undo cases, or calculated always...
3) I don't know... is my best solution to have a Remove() variation that bypasses privilege checks if the child item IsNew ?

RockfordLhotka replied on Friday, October 09, 2009

There are a couple possible solutions. First though, it is important to understand what data binding is doing.

When the user selects an item in the datagrid, that item's edit level is elevated because the item has currency. When the user moves off that row CancelEdit() or EndEdit() is called, which decrements the edit level - of course now some other row will have currency.

For a new item that has no changes, binding knows to call CancelEdit() - well, these days it actually uses the ICancelAddNew interface on the collection - to remove the new-but-unchanged item.

Any change to the new item though, means EndEdit() is called, because the item has been changed and it is assumed the user wants to keep it. If they didn't want to keep it they'd have pressed ESC (which would have reset the row to be unchanged) first right? :)

If you have a dialog window and that window uses data binding, THAT WINDOW has its own currency. Actually it isn't the window, it is the bindingsource. But the point is that the window will have currency.

It is almost certainly the case that data binding sees the dialog having currency as a reason to do an EndEdit() on the row. In other words, data binding no longer thinks the item is "brand new" and so it won't auto-remove it anymore.

I haven't tried this, but I bet you'd have the same problem with a DataTable too - because I think this is a currency issue at the data binding level.

In other words, you'll probably need to have code-behind the main form that understands that

  1. the item is new
  2. the user clicked cancel in the dialog

and therefore knows to explicitly remove the new item from the collection via the bindingsource.

Copyright (c) Marimer LLC