CSLA 3.0.5 / 1-Level Undo ?

CSLA 3.0.5 / 1-Level Undo ?

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

sigmondzavion posted on Tuesday, September 01, 2009

We are stuck (for the time being) on version 3.0.5.

Going through many posts, source code and testing - I have come to the conclusion that N-Level and DevExpress XtraGrid do not play well together - mainly due to the unpredictable nature of XtraGrid's calls to BeginEdit(), EndEdit(), & CancelEdit(). There is also issues with DataGridView, as well. We have several levels in our hierarchies and need dependable handling of master-detail relationships while data binding.

Therefore, I am thinking about modifying CSLA 3.0.5 to handle 1-Level Undo as well as N-Level. I plan to add an enum property like "UndoMode" (Standard, 1Level).

My question is - Does anyone see any show-stoppers that I may run upon?

RockfordLhotka replied on Tuesday, September 01, 2009

You could back-port the changes to n-level undo from 3.7 back into 3.0.

Any time you touch n-level undo it is risky because there are so many complications with data binding. It might be safer and easier to do the back-port than to invent a whole new model.

Basically the changes (in 3.5 originally) simply ensure that calls through IEditableObject only affect the current object, not the child objects. That emulates the behavior of the DataSet, which is what these grid controls are expecting.

None of the changes require new .NET features - they are simply passing extra parameters to some methods and using those values to short-circuit some of the "normal" n-level undo behaviors.

sigmondzavion replied on Wednesday, September 02, 2009


Thanks for the prompt reply.

I will consider the back-port, as you mentioned.

In the meantime, I am observing the behavior when setting BusinessBase.DisableIEditableObject to "true". We would call Root.BeginEdit() before binding the hierarchy (as you have exampled). This would give us the capability of rolling back (cancelling) changes in memory OR comitting them. It looks like this may be sufficient for our needs, at the moment.

RockfordLhotka replied on Wednesday, September 02, 2009

Yes, that is also a workable solution - though it does mean users won't be
able to press ESC while editing a row in a datagrid to roll back changes to
that row.

rsbaker0 replied on Wednesday, September 02, 2009

Actually, this is possible also -- you just have to hook the ProcessGridKey event and call CancelEdit() and then BeginEdit() again. (Or, if the object is brand new, then it should simply be discarded, which can be done by calling RemoveCurrent() on the associated BindingSource)

With DisableIEditableObject, it seems the rules about not making certain calls on the object (e.g. BeginEdit, Save, etc.) while it is bound no longer apply -- at least it appears to work fine. I don't see why it would not since the object ignores any calls being made through the IEditableObject interface.

What we did was implement an "EditManager" supervisor class that hooks a few events on the DevExpress Grid itself as well as an associated BindingSource. For example, each time you get a CurrentChanged, you can apply the changes to the "previous" current object and then call BeginEdit() on the new current.

Copyright (c) Marimer LLC