Funny you should mention it, we've actually just added two methods to the business layer today to handle this exact thing. They allow you to save a snapshot of the entire datatable within a business object and then restore that snapshot if needed at a later time (without necessarily changing the edit state.) Before getting into the long explanation of what the new stuff will allow you to do (once it is released, of course ), the short of it is that you are on the right track and can indeed handle it by storing off the existing state and then restoring that state on an incrimental undo.So now, the big long explanation of the what the new stuff will look like . First, the new business object methods:
- BusinessObject.SaveCurrentDataTableToSnapshot() - Saves the current datatable to a snapshot. This snapshot is handled internally to the business object and, as such, does not need to be saved to a local variable. Only one snapshot can be saved at a time, so calling the method a second time will overwrite the existing snapshot.
- RestoreCurrentDataTableSnapshot(refreshUI As Boolean) - Restores the BO's datatable to match the existing snapshot. Obviously, if this is called before the SaveCurrentDataTableToSnapshot() method an exception will be thrown (since there is no snapshot to restore.)
In our medical application, your issue manifested when calling a child from from a listview using the childformdialog class. Since we had to undo the datarow (just like you are doing) when cancelling out of a child form dialog, it would not allow you to add a new record, accept it, then edit it and cancel out without saving the parent record in between (cancelling out the second time would undo the currentrow and discard the added record alltogether.) The same would happen when editing an existing record once, accepting the changes, then editing a second time and cancelling the changes (the undo would cause the record to revert all the way back to the original state, losing the first edit's accepted changes.)
To fully utilize these new methods, we have also added functionality to the listview to automate some of the process. I'm not sure whether Trent has mentioned it yet, but the listview has been enhanced to handle ChildFormDialogs much more smoothly (you basically tell it what the add, edit, and delete objects are, the BO it is supposed to handle, and the ChildDialog to call and it does the heavy lifting for you.) In addition to this, we added an AutoSnapshotBusinessObject property, which defaults to true. When set to True, a snapshot will be taken automatically on an Add or Edit. By handling the (also new ) ChildFormResults event of the listview, you can check to see whether the dialogresult was Cancel and, if so, restore the state.
So, bottom line, once you get the properties lined up with the new stuff, this is all the code you'll end up needing to make everything above work:
Private Sub lstYourListBox_ChildFormResults(ByVal sender As System.Object, ByVal e As MicroFour.StrataFrame.UI.Windows.Forms.ListViewChildFormResultsEventArgs) Handles lstYourListBox.ChildFormResults
If e.Results = DialogResult.Cancel Then
'-- Restore the state of the child BO on a child form cancel
InsuranceCarrierNotes.RestoreCurrentDataTableSnapshot(False)
End If
'-- Requery the list
e.Requery = True
End Sub
All of which is great once you get the new stuff, but in the mean time, you can do pretty much the same thing manually by saving off the state to a temporary variable and then restoring it as needed, just as you are doing.
[Edit]
Just as an after the fact disclaimer: the above is a description of how it currently works, but may not be exactly how it works in the final release. We will likely tweak it a bit before releasing it to the masses (i.e. we are considering adding the ability to store more than one snapshot), so be sure to check the help files on it when you get the release .