This project has moved. For the latest updates, please go here.

Registering with 'ListChanged' event

Developer
Apr 23, 2013 at 6:19 PM
I'm trying to create a typical invoice object (Invoice/InvoiceDetailList/InvoiceDetailListItem) and have discovered the only way to subscribe to the 'ListChange' event of 'InvoiceDetailList' is in the 'FetchChildren' method of the of 'Invoice' (see below). Unfortunately, this code is in the designer file and is overwritten with subsequent generation. I've tried placing this in the 'Child_Create' override in the non-designer file but this event does not get raised. I've also tried the 'OnGetChildren', 'OnSetChildren' and 'OnChildChanged' and none of the events are raised. I thought I remember reading somewhere these events won't get raised if the child is a managed property but I've I've tried the Declaration Type to 'Classic' and this did not work. Can someone help please.
        /// <summary>
        /// Loads child objects from the given SafeDataReader.
        /// </summary>
        /// <param name="dr">The SafeDataReader to use.</param>
        private void FetchChildren(SafeDataReader dr)
        {
            dr.NextResult();
            LoadProperty(DetailLinesProperty, InvoiceDetailList.GetInvoiceDetailList(dr));
            DetailLines.ListChanged += DetailLines_ListChanged; <<----
        }
Coordinator
Apr 24, 2013 at 12:00 AM
Edited Apr 24, 2013 at 12:07 AM
Hi Keith,

On CSLA objects the usual place to attach event handlers that you want to run always is:
  • constructor
  • OnDeserialized
The constructor is indeed overwritten each time you regenerate but OnDeserialized is on the extended file and "survives" regeneration. Never thought about this but maybe a Generate Constructor option in 00. Generate Options might be useful enough. It would be used like this:
1) generate object with constructor
2) copy the constructor to the extended file
3) change the constructor as you see fit
4) change the Generate Constructor to false

Your question brought up a few threads in CSLA .NET forum:

a) 3.8 ListChanged vs. 4.1 CollectionChanged
Instead of ListChanged you should use ChildChanged

b) Add Business Rules for Business List Base child property
Instead of attaching an event handler, you can override OnChildChanged as follows
protected override void OnChildChanged(Csla.Core.ChildChangedEventArgs e)
{
    base.OnChildChanged(e);

    // If attached to a property
    PropertyHasChanged(DetailLinesProperty);

    // or if attached at object level (this was introduced in Csla 4.2.0)
    CheckObjectRules();
}
And why is this the preferred way of doing things?

Because of

c) ChildChanged Event not firing in CSLA 4.3 when using SQL Server Session State
CSLA will rehook the ChildChanged event handler for child collection but NOT rehook YOUR event handler that you set to listen for ChildChanged. So the child changed event is raised (as proof by the OnChildChanged method is called) but YOUR eventhandler code is not called because it is unknown after deserialization.
So I guess no changes to CslaGenFork are needed in order to satisfy your requisite.

Regards
Tiago Freitas Leal
Coordinator
Apr 24, 2013 at 12:20 AM
Edited Apr 24, 2013 at 12:34 AM