Undo with child forms

Undo with child forms

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


Adriano posted on Monday, June 19, 2006

Hi.

I have a parent object (ordCliente) on OrdClienteFrm form and its details (collection=OrdCliDettaglioS, child=OrdCliDettaglio) on a listview on the same form.

I'm using databinding for ordCliente on the form while the listview is programmatically filled whith the OrdCliDettaglio details within sub lvwOrdCliDettaglioSRefresh().

OrdClienteFrm data and child OrdCliDettaglio items can be edited only after I press the edit button on the OrdClienteFrm form which calls the parent BeginEdit(). Later the user can only press the Save or Cancel buttons which call parent ApplyEdit() or CancelEdit().

While in Edit, doubleClicking the list view a child OrdCliDettaglioFrm form is loaded, the child BeginEdit() is invoked and OrdCliDettaglio object is passed to the form.
In the child OrdCliDettaglioFrm form the various child fields can be edited. Pressing Save buttond on the OrdCliDettaglioFrm form the child ApplyEdit() is invoked.

If I press the Cancel button on the parent OrdClienteFrm form the parent CancelEdit() is called. At this time the listview is cleared and re-filled with all its details reading the OrdCliDettaglioS collection. The collection IS NOT "rolled back" to the original state. Data in the parent object are correctly rolled back.

Something appens when I bind child data on the child form.

As someone solved something similar to this?

Any kind of suggestion is appeciated...

Adriano

-----------
Some code:
-----------

 ''''''''''''''''
 ' Child data modified programmatically
 ' This works!!!
 ' 
 Private WithEvents mObj As OrdCliente
 ... 
 mObj.BeginEdit()   'OrdCliente data are saved.
 ...
 Dim ID As Integer = CInt(Me.lvwDettagli.SelectedItems(0).Text)  'to select the ID
 Dim chld As OrdCliDettaglio = mObj.OrdCliDettaglioS.GetItem(ID) 'to get the child
 With chld
    .BeginEdit()
    .idMastro = "050301" 'edit some data programmatically...
    .Quantita = 100   'edit some data programmatically...
    .ApplyEdit()
 End With
 lvwOrdCliDettaglioSRefresh()  'edited data are correctly showed
 ...
 mobj.CancelEdit()   'Cancel update on parent object
 lvwOrdCliDettaglioSRefresh()  'edited data are correctly rolled back to original values

 

 ''''''''''''''''
 ' Child data modified within a form
 ' This DOES NOT work!!!
 ' 
 Private WithEvents mObj As OrdCliente
 ... 
 mObj.BeginEdit()   'OrdCliente data are saved
 Dim ID As Integer = CInt(Me.lvwDettagli.SelectedItems(0).Text)   'to select the ID
 Dim chld As OrdCliDettaglio = mObj.OrdCliDettaglioS.GetItem(ID)   'to get the child
 '
 Dim Frm As New OrdCliDettaglioFrm   'form for data editing
 Frm.SetObj(chld)              'OrdCliDettaglio data passed to form
 Frm.ShowDialog(Me)      'edit the data
 If Frm.Ok Then
    chld.ApplyEdit()
 Else
    chld.CancelEdit()
 End If
 lvwOrdCliDettaglioSRefresh()  'edited data are correctly showed
 ...
 mobj.CancelEdit()   'Cancel update on parent object
 lvwOrdCliDettaglioSRefresh()  'edited data are NOT rolled back to original values.

 

 ''''''''''''''''
 ' This is the code on child OrdCliDettaglioFrm form used to receive the object to edit...
 '
 Private WithEvents mObj As library.OrdCliDettaglio
 ...
 Public Sub SetObj(ByVal obj As library.OrdCliDettaglio)
    mObj = obj
    Me.objBindingSource.DataSource = mObj  'to bind all fields
 End Sub

RockfordLhotka replied on Monday, June 19, 2006

I think you are running into an issue that has been discussed here, and which generated errata on my web site: when using a bindingsource object you need to call EndEdit on the bindingsource object rather than calling ApplyEdit on the object itself.

However, based on what you are finding, I'm now thinking that you should call CancelEdit on the bindingsource rather than on the object itself, thus ensuring that data binding is kept in the loop all the way through. Can you try that and see if it works?

Adriano replied on Tuesday, June 20, 2006

Thank you for your help.

I added a objBindingSource.CandelEdit() and it works.

Now the Cancel button calls the following (both CancelEdit are required to work):

...
Me.objBindingSource.CancelEdit()  'This makes things working
mObj.CancelEdit()
...

That does not solve the following problem:

- If data is modified and cancelled twice, the first time it is rolled back, the second time it is not. This can be riproduced on the Project Tracker 2.0 as well.

Someway I can avoid users to edit and cancel twice the same object but may be there is a better solution.

This sequence does not work only for child collections within the object:

1)  Get data from DB into the mObj object (with a child collection)
2)  Bind the object to the form
3)  Press Edit button (mObj.BeginEdit() is issued)
4)  Edit one or more items in the child collection using a Form
5)  Press Cancel Button (objBindingSource.CancelEdit() and mObj.CancelEdit() are issued, as mentioned above)
6)  Child data are correctly rolled back to original situation of point 2.

7)  Press Edit button again (mObj.BeginEdit() is issued)
8)  Edit one or more items in the child collection using a Form
9)  Press Cancel Button again (objBindingSource.CancelEdit() and mObj.CancelEdit() are issued)
10) Child data are NOT rolled back to original situation of point 2 == point 7. They maintain the modified value.

 

Lnk replied on Tuesday, June 20, 2006

Hi all...

About cancelling multiple times:

I think you should call BeginEdit again after calling CancelEdit for taking a new object snapshot.

We got into the same situation and resolved it that way.

Hope that helps.

Emilio

 

Copyright (c) Marimer LLC