Vibrant discussion about CSLA .NET and using the framework to build great business applications.
I know this type of question has been rehashed time and time again and I should think that forum members are probably sick to the back teeth with this subject but I have looked high and low on the web for a solution to a problem and I just can't seem to get a sensible solution.
I am using CSLA 3.7, I have a Winform with three controls bound using a binding source to a Business base derived object that is an editable root with a child collection. The collection is bound to a Dev Express grid. The collection consists of a single value for each item that I want to edit "in grid". I am using the Bind and Rebind methods as suggested in the forums.
Everything appears to work correctly as far as undo is concerned. I change a property on the root object, press my undo button and everything rebinds and works fine. I change a value in the grid, press escape, and the field reverts back to its previous value. So I know the mechanism is working perfectly and the Dev Express grid is working as it should in terms of BeginEdit, CancelEdit and EndEdit.. Note I want to re-iterate - the grid IS working as it should.
The problem is this is not the desired behaviour I require. I want to be able to undo all the changes made to the child collection when I press the undo button. I have tried combinations of begin edit, end edit, taking cloned snapshots (the problem is with the latter is I could end up rehashing all the N-level undo code in my UI!), and all I seem to get is the EditLevel mismatch error. Hours of research and trial and error have resulted in no progress whatsoever.
Another issue I wish to implement is to recover from save errors and rebind the UI to a snap shot of the object graph to it can be rebound with undo history still intact. Surely if business logic exists within the database as well as business objects then when an error is detected and returned through the data access layer, the user will want to correct the error. In my opinion this is a fundamental requirement that seems to have been overlooked (purists will say this should occur BUT in some cases business logic needs to be replicated or can only occur within the database - concurrency issues being a typical example).
It seems I am jumping through hoops to solve a very simple and common problem. From articles I have read on this and the dev express forums it seems that very complex solutions are offered. I believe the solution is probably very fundamental.
So can someone please help me solve this problem - am I using the correct control (each row in the grid only has one value to edit). Is there something I should be doing in the child collection? Can I override the edit level changes in the parent and cascade through all the children?
Your description here is exactly as Windiows Forms Databinding should normally work.
When your objects are databound you should never call BeginEdit/CancelEdit or EndEdit so the semantics would be like this:
1. call root.BeginEdit2. set up databinding to connect UI to business objects
Undo:10. disconnect databinding 11. call root.CancelEdit12. call 1) to setup databinding
You may have a "larger" undo but that can only be used when object is not active in databinding.
Ie - WinForms databinding assumes it has full control on the Begine/Cancel/EndEdit process so if you want to control it yourself then it must be done with objects that are not active in databinding. Hence before your form is connected to business objects or after they are disconnected.
Jonny Bekkum, Norway
I think this makes sense now and I can correct my code to make it work correctly. I well let you know how I do!
Thank you for your help