Handling WPF Databinding Issues When a Property Change in One Member of the Collection Changes How Other Business Objects Are Displayed

Handling WPF Databinding Issues When a Property Change in One Member of the Collection Changes How Other Business Objects Are Displayed

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

JonStonecash posted on Saturday, March 12, 2011

Some background:  I have a CSLA 4 + WPF/MVVM application.  I have a collection of business objects exposed on the view model as a property.  Each business object represents a Nutrient that has a formal name, an easier-to-read alias, a value and a possible equation that can compute the value by referencing other Nutrients.  The equations are expressed using the formal names, but are displayed and edited using the alias names.  There is logic in the business object to map between the formal names and the alias names.  That is all working.

We have a UI that exposes the list of Nutrient business objects as a WPF grid and allows the user to change two things: the alias and the equation.  The requirement is that if the user changes the alias of one of the nutrients, the rows that contain equations that refer to that nutrient should be redisplayed.  Note that these business objects have not changed: the displayed equation is a computed value based upon the state of the collection.

My problem is how do I get WPF databinding to redisplay the list.  I have wired up the business object list object to listen for the property changed events for each member of the list, check for the alias property, and raise an event that is caught by the view model.  In that event handler, I can trigger the needed actions.  That wiring is all working. 

My initial assumption was that I could trigger the redisplay this by raising the PropertyChanged event on the view model list property and databinding would redisplay the list by calling the properties of each business object in the list.  That is not happening: no calls to the other business objects and no changes in the other rows of the grid. 

My next thought was that I could bind to a LinqObservableCollection (the set of nutrients is filtered) and rebuild the list each time that a nutrient alias change occurred.  That works (in the sense that the changes in the other rows are visible) but fails when I try to ApplyEdit on the underlying list.  The edit level of the altered child is 2 and that is one two high.  I should mention that we do a manual BeginEdit on the underlying collection when the view model starts. 

If I were using WinForms rather than WPF, I would go through an unbinding and rebinding operation, but I have no clue as to how to do that with the MVVM approach.  [I have been doing the business objects and data access work on this project and am trying to lend a helping hand on the UI side.]

Jon Stonecash


sergeyb replied on Saturday, March 12, 2011

Yes, raising property changed for entire collection does not refresh list controls.  I would instead handle this in the CSLA object itself via rule on alias property.  Inside the rule I would enumerate through siblings and call some method like RefreshBecauseAliasChanged in which I would fire PropertyChanged for whatever properties you need to refresh.  You can go a step further and pass in changed nutrient so that each sibling would check first to see if it cares about this nutrient, then fire property change for those properties that needs to be refreshed.

JonStonecash replied on Saturday, March 12, 2011

I did what you said to do and it worked.  Thanks for the help.  I kept thinking that it would easier and more efficient to do the whole list rather than one object at a time. 

Copyright (c) Marimer LLC