I have a list of BusinessBase<T> objects loaded from the database. These are rather complex objects as they contain two BusinessBindingListBase properties which are children and one of those lists is of BusinessBase<T2> which also contains a BusinessBindingListBase<> of other BusinessBase<T3> objects.
The first list is a DynamicBindingListBase<T> which should update the objects when the current pointer changes on the Form BindingSource. The initial form cannot possibly display all the complex data so showing the list and the header level information on the base or parent object is sufficient for the end user. However when the user wants to view / edit more data for that specific object, they can click on a button that will open an editor form which displays all the data for that single object (child and grandchild lists)... The problem is "how to save the object when the data has changed" because it is bound in the first form (showing the list of multiple items). Do I need to share the BindingSource of the original form so I can call EndEdit() to manually save when the object is changed?
You may look into this article by Tiago for clarification:
These are rather complex objects as they contain two BusinessBindingListBase properties which are children.
|blue masking tape|
Quote from the C# 2008 Business Objects book:
"Dynamic Editable Collection
The dynamic editable collection stereotype is designed to support a narrow and focused scenario in
which the UI is a Windows Forms grid control that is data bound to the collection, and in which the
user wants his changes to each row saved as soon as he moves off each row. "
IE: DynamicListBase i s created to support edit of a "simple" editable object that has no child lists.
So the typical solution wold rather be:
I believe you are stretching the limits for what DynamicListBase is meant to support.
I think you are right about my use of DynamicBindingListBase<> where I am stretching (abusing) the intended use of it.
The next logical question is then how would I rig the form to update the EditableRoot object where the root elements are bound, the EditableChildList (s) are bound to relevant data grids, and EditableGrandchild objects are displayed in a repeated UserControl.
Because the child objects are marked IsChild=true I cannot use a DynamicBindingListBase to display these so the change in focus or change of current item will not trigger the save. (Child objects cannot call Save() directly...)
I'm not clear if I need to provide a button that will call ApplyEdit() on the BindingSource, and as there are several BindingSources on the same page, will ApplyEdit() on the EditableRoot end the edit session on each of the child objects?
I intend to write a proof of concept and upload it to CodeProject.com. I hope then solving this puzzle will help many more developers than just me.
My next post here will be with the link to CP....
Well, maybe you could start by explaining the use case / requirements that you have?
I have a Proof of concept project that should be attached here which is the code for the following requirements. This is not my company's code, but it is the exact relationship between objects I'd like to get working with CSLA. I hope that if this is a strong enough example for other developers to learn from that it can be added to the CSLA samples! It looks like I need to use the CslaActionExtender class, but I'm just starting to learn about this class.
I feel I have to abandon the hopes of making the EditableRoot object save every time a property is changed. I would like to create a special PropertyInfo class that can invoke or raise a save event where the CslaActionExtender will listen to and then automatically perform it's actions to unhook events, save, and rebind the new object... I think having the ability to automatically save an object when it is validated will reduce some small tasks for the User and if there is an error, it will be displayed in the form and then when they correct the field it is then automatically saved again...
EditableRoot - Can create an instance as New(), or Get() from dto.
Properties - Index, Class Index, Name, Description, Collection of EditableChild1 objects,
Collection of EditableChild2 objects each with Collection of EditableGrandchild objects,
*** Compute the following: GrossValue, NetValue.
EditableRootDto - Load properties from datasource...
EditableRootClass - Acts as dropdown selection as a descriptor for EditableRoot.
EditableRootDynamicList - Automatically save the EditableRoot objects as they are modified. (perhaps a special
EditableChild1 - Can create an instance as New(), or Get() from dto.
Properties - Index, Class Index, Name, Description,
*** TaxPercentRate, TaxAnnualRate
EditableChild2 - Can create an instance as New(), or Get() from dto.
Properties - Index, Class Index, Name, Description, Collection of Child objects,
*** GrossValue, NetValue
EditableGrandchild - Can create an instance as New(), or Get() from dto.
Properties - Index, Class Index, Name, Description
*** MaintenanceCost, MarketValue, PurchaseValue
*** When specific properties on the EditableRoot, EditableChild1, EditableChild2, and EditableGrandchild
objects are modified then through the relationship (object graph) the EditableRoot will have to
recompute/recalculate some specific values which are necessary for display in the UI. These are
READONLY properties and should NOT cause any object to be marked as ISDirty. (with exception one total
on the EditableRoot that may be persisted for computation in other downstream processes)
I've updated the solution file to include Tiago Freitas Leal's latest version of the CslaActionEctender in the Csla.Windows project. His work is documented here: http://forums.lhotka.net/forums/t/8009.aspx
The attached file contains an updated and more functional version with the binding on two forms enabled. There are still some bugs with CslaActionExtender in this version (4.3.10 V3) just fyi for Tiago.
((((( Correction:::: I'm NOT sure there are any bugs in CslaActionExtender v3... I had found an issue where a bug would occur when updating a property of a child object but it was unhandled and bubbled up to CSLA which threw the error. I did however notice that the Save and Cancel buttons do not disable when saved for the first time. I would think that should create a state where there was nothing to do.))))
To me, there is a lot of complexity added because the Save/Update process (also required for the Undo functionality) automatically makes a Clone of the object and that is the object returned by the update process. The result is the issues with rebinding the data when saving. This makes it difficult if not impossible (by complexity...) to have multiple forms bound to the same object because if one commits (save/update) then that form will have a new object (clone) to rebind but then multiple forms would also have to handle the replacement of the new object. This is even more complicated when the bound object in one form is a member of a list in another form.
If the save process didn't clone and return the new object then everything would be copacetic. Then there is a new problem of how to transmit and return data to the source. This could be enforced by the use of Dto's for every communication. It is not much different than Clone, but I don't now about the performance. I suspect Clone is much faster than creating and loading an object, unless the only thing l loaded to Dto is a few fields to persist; and not the entire business object with logic and tons of other data...
I'm curious if it is possible that the Windows version of Csla could be more easy to use if it was split from the asp.net xaml etc version?
I believe you are stretching the limits for what DynamicListBase is meant to support..
|property management everett washington|
Copyright (c) Marimer LLC