Child collection PropertyChanged() notification on parent.

Child collection PropertyChanged() notification on parent.

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


gajit posted on Thursday, March 26, 2009

Hi guys (long time, no annoy),

This is an oldie - but looking through the forum I can't see a CSLA 2.1 VB.Net documented response for this.

I have a parent BO with a child collection - customer and customer contacts, my issue is that when i change a value in one of the child rows, the propertychanged event gets fired - but nothing then passes that back to the parent. As my UI enables/disables buttons, etc based on the mCUSTOMER_PropertyChanged event, nothing 'fires' the correct enabled states, etc.

I'm assuming I have to override the PropertyChanged on my child collection and in there do something to update the PropertyChanged on the parent - but I'm a little vague on how to implement that - I see from other posts that there is also an OnDeserialized event that needs overriding...

My apologies for posting what is clearly an older and probably often-asked issue, but I've been developing with CSLA happily now for a number of years, pretty much problem free. Seems strange that I wouldn't have encountered this problem before - but I do tend to avoid the single parent - child UI form where possible (I usually drill down and open individual BO's for the children). But in this case I need to show both.

If anyone can point me in the right direction maybe with a snippet, that would be very much appreciated.

Thanks,

Graham

 

 

 

 

 

gajit replied on Thursday, March 26, 2009

OK.. I'm getting a wee bit frustrated with this....

I've sifted through the forums... and although I can't find a good VB example I took a crack at it...

Here's what I have...

Parent BO is Customer

I have created a Property;

Public Property ChildHasChanged() As Boolean

Get

CanReadProperty(True)

Return mChildHasChanged

End Get

Set(ByVal Value As Boolean)

CanWriteProperty(True)

If mChildHasChanged <> Value Then

mChildHasChanged = Value

PropertyHasChanged()

End If

End Set

End Property

The children are defined;

Private mCONTACTS As CustomerContacts = _

CustomerContacts.NewCustomerContacts()

 

Public ReadOnly Property CONTACTS() As CustomerContacts

Get

Return mCONTACTS

End Get

End Property

 

I added a handler in an over-ridden event in the Customer BO;

Protected Overrides Sub OnDeserialized(ByVal context As System.Runtime.Serialization.StreamingContext)

MyBase.OnDeserialized(context)

AddHandler CONTACTS.ListChanged, AddressOf CustomerContacts_ListChanged

End Sub

and

Private Sub CustomerContacts_ListChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ListChangedEventArgs)

PropertyHasChanged("ChildHasChanged")

End Sub

I haven't changed anything in the child collection class.

 

The "important" pieces of my UI are;

Public Sub New(ByVal customer As Customer)

InitializeComponent()

mCUSTOMER = customer

mCUSTOMER.BeginEdit()

Me.CustomerBindingSource.DataSource = mCUSTOMER

ApplyAuthorizationRules()

End Sub

 

Private Sub mCustomer_PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Handles mCUSTOMER.PropertyChanged

ApplyAuthorizationRules()

End Sub

and

Private Sub SaveCustomer(ByVal rebind As Boolean)

Using busy As New StatusBusy("Saving...")

' stop the flow of events

Me.CustomerBindingSource.RaiseListChangedEvents = False

' do the save

Dim temp As Customer = mCUSTOMER.Clone

temp.ApplyEdit()

Try

mCUSTOMER = temp.Save

mCUSTOMER.BeginEdit()

If rebind Then

' rebind the UI

Me.CustomerBindingSource.DataSource = Nothing

Me.CustomerBindingSource.RaiseListChangedEvents = True

Me.CustomerBindingSource.DataSource = mCUSTOMER

ApplyAuthorizationRules()

End If

Catch ex As Csla.DataPortalException

MessageBox.Show(ex.BusinessException.ToString, _

"Error saving", MessageBoxButtons.OK, _

MessageBoxIcon.Exclamation)

Catch ex As Exception

MessageBox.Show(ex.ToString, _

"Error saving", MessageBoxButtons.OK, _

MessageBoxIcon.Exclamation)

Finally

Me.CustomerBindingSource.RaiseListChangedEvents = True

End Try

End Using

End Sub

BUT, when I open my form, and make a change to some data in one of the CHILD rows, NOTHING happens. In fact, I set breakpoints in the Customer BO, where I added the handler in the deserialize - and NOTHING gets triggered.  Am I missing something???

Any help wuld be appreciated - getting very frustrated here...

Graham

 

 

 

 

 

 

 

gajit replied on Thursday, March 26, 2009

OK, I think I have it figured out.

 

I placed the AddHandler in the DataPortal_Fetch of my parent BO, AND in the overriden OnDeserialized

AddHandler CONTACTS.ListChanged, AddressOf CustomerContacts_ListChanged

The CustomerContacts_ListChanged subroutine resides in the same object;

Private Sub CustomerContacts_ListChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ListChangedEventArgs)

PropertyHasChanged("ChildHasChanged")

End Sub

And all seems to be working as required. Got there in the end.

Gajit.

 

 

shawndewet replied on Saturday, March 28, 2009

How 'bout upgrading to v3.6 and overriding the OnChildChanged in your parent class?  Very nice mechanism!

dg78 replied on Saturday, March 28, 2009

It is strange.

 

Your children are ReadOnly :

Public ReadOnly Property CONTACTS() As CustomerContacts

 

How can you change a value in one of the child rows ?

Copyright (c) Marimer LLC