I have a list of children on my object, let's call them costs. I've got 2 'views' for the costs for the end user, one of which shows the actual list, the other which shows a calculated list which is based on the original list.
I've added a new readonly property to my object and written code to calculate the items which should be in the list by building a new costs collection on the fly (when the source list changes), however, when I bind this to my control, the changes to the underlying list are not reflected in the calculated property.
This wasn't a suprise, as when the underlying list changes, it doesn't tell the readonly property that any values have changed. I thought I'd need to get the bindingsource to notify the UI that a property had changed and this would cause it to re-read (and re-build) the readonly property. I added a call to OnPropertyChanged() when the source list changes. This gets fired when I add/remove items from the list but the UI still doesn't update.
Do I need to register the field with FieldManager for the databinding to work properly with the UI?
Is this calculated property on the BLB or a parent BB?
It needs to be on the parent BB. Properties on list objects don't generally bind properly - data binding isn't set up to bind to list properties.
If the property is on the BB, then it is that object that needs to call OnPropertyChanged for that property. Since this is calculated based on child objects changing, you'd typically override OnChildChanged in this parent object, and that's where you'd trigger the rule that calculates the value.
Yes that's exactly what I've done: I've got the following
Parent - costs property (collection of costs)
- Child Collection of Costs
- Cost 1
- Cost 2
- Calculated Collection of Costs
- Virtual cost 1 etc
The parent handles ChildChanged and looks at type of e.ChildObject to decide what to do, but I don't have the calculated property registered on the field manager. Would calling PropertyHasChanged("fieldName") cause the UI to be updated even if the field had not been registered?
I'm currently changing the implementation so that the fieldmanager registers the property and my ChildChanged event regens the property and calls SetProperty on the new field - I know this will raise a property changed event so if that doens't work it must be something else that's not right
Typically for a purely calculated field where you don't store the value you don't need to register the property with the field manager. You can just use OnPropertyChanged("PropertyName") to get the UI to re-read the property value.
However, if you are storing the calculated value, it is probably best to create a normal read-only property using the field manager. And in that case you might (at least in CSLA 4) implement the calculation as a business rule, attach that rule to the property and then in OnChildChanged just call BusinessRules.CheckRules(MyCalculatedProperty) to run the rule.
I've now registered the field in the fieldmanager and regenerated the field when needed - however I still have the issue with the form not updating - I'm going to build a couple of test forms to check this out as I think somewhere down the line the usercontrol I'm binding to must be looking at a copy of the object.
Maybe another dev threw a layer of complexity in for job security :)
Yep, looks like there's an issue with the usercontrol nested on the form I'm using. If I throw a datagrid on top and bind it to the collection it's receiving the updates without issue!
Back to the drawing board!
Copyright (c) Marimer LLC