3.8 ListChanged vs. 4.1 CollectionChanged

3.8 ListChanged vs. 4.1 CollectionChanged

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


DaveStorey posted on Monday, July 25, 2011

Hi,

I'm relatively new to CSLA so I apologise in advance has an obvious answer that I am missing.

We have recently moved from v3.8 to v4.1 and in doing so have moved all of our old validation rules to business rules and all of our ListChanged event handles to CollectionChanged event handlers. In doing so we have noticed some odd behaviour whereby if we change a property on a child collection item the CollectionChanged event does not fire. It would appear that the collection changed event does not seem to bubble up to the parent object any more unless there is a change made to the actual collection object. An example being a parent table with child rows:

Table.OnCollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler();

Table.Add(newRow) - The event fires
Table[0].Name = "Bob";  - The event does not fire

It might be worth mentioning at this point we attach our event handlers on both the property setter for our collection and also on the OnDeserialized event for our object.

We have rolled our code back to v3.8 and checked this behaviour and it would seem that the ListChanged event is firing in both the example circumstances. 

Is there a new event we should be using instead of CollectionChanged? Or is this new behaviour by design?

Regards,

Dave

RockfordLhotka replied on Monday, July 25, 2011

The core behavior around ListChanged and CollectionChanged is defined by Microsoft, not CSLA. Because BindingList and ObservableCollection are different types, they have different behavior. And those are the two base classes from which the various CSLA collection types derive.

You might be better off using ChildChanged. This is a CSLA event that bubbles up through the object graph, and should provide consistent behavior for both collection types.

DaveStorey replied on Tuesday, July 26, 2011

Thanks Rocky for the quick response. That ChildChanged event does seem to provide the functionality that we were expecting once we changed our event setters to use the SetProperty rather than LoadProperty.

As a quick side query is there any helper methods to tie a PropertyInfo to the event args returned by the ChildChanged event? I have noticed when manipulating a collection the ChildChanged event is raised 4 times in the following sequence: Count changed, Item[] changed, CollectionChanged and then finally my custom object property changed. Of these I am only interested in the final event as it is going to be used to re-evaluate a business rule. At present my event handler just calls PropertyHasChanged(PropertyInfo) but am worried that this may cause a performance hit to the system dependant on the complexity of the business rule. I want to filter out the event calls that don't relate to my PropertyInfo but the only way I can see to do this is:

if (e.PropertyChangedArgs.PropertyName == MyPropertyInfo.Name)
{
PropertyHasChanged(
MyPropertyInfo);

Any help or advice would be appreciated,

Dave

JonnyBee replied on Tuesday, July 26, 2011

Hi Dave,

You should implement as you suggested.

Events may occur from several places and your suggestion is the proper way to handle this.

DaveStorey replied on Tuesday, July 26, 2011

Thanks guys, appreciate the help

Dave

RockfordLhotka replied on Tuesday, July 26, 2011

You can filter based on the args information provided to your ChildChanged event handler though. For example, when Count has changed maybe you don't do any work, because that doesn't affect you.

Copyright (c) Marimer LLC