Problem with own Event in derived BusinessBase and ResetBindings on a formProblem with own Event in derived BusinessBase and ResetBindings on a form
Old forum URL: forums.lhotka.net/forums/t/7813.aspx
Mats posted on Monday, October 19, 2009
Hi all !
I am using CSLA 2.14 and have a class that derives from BusinessBase(of T) to implement an event named MyBusinessBase.
In a form there are AddHandlers for PropertyChanged and my event as well.
There is also a BindingSource for myObject (derives from MyBusinessBase) and in case of filling the form data (at the beginning or in case of saving) I do the following:
<BindingSource>.RaiseListChangedEvents = False
<BindingSource>.EndEdit()
... maybe saving object ...
<BindingSource>.DataSource = Nothing
<BindingSource>.DataSource = myObject
<BindingSource>.DataSource.RaiseListChangedEvents = True
<BindingSource>.DataSource.ResetBindings(False)
The last statement (ResetBindings) causes an error that the form is not serializable.
If I remove the AddHandler of my own event, everything is ok.
By removing the ResetBindings statement the problem is gone too while my event is fired and received.
MyBusinessBase looks that way:
<Serializable()> _
Public MustInherit Class MyBusinessBase(Of T As MyBusinessBase(Of T))
Inherits BusinessBase(Of T)
Public Delegate Sub SomethingChangedHandler(ByVal sender As Object, ByVal reason As Object)
<NonSerialized()> _
Private mSomethingChangedNonSerializable As SomethingChanged Handler
Private mSomethingChangedSerializable As SomethingChanged Handler
Public Custom Event SomethingChanged As SomethingChangedHandler
AddHandler(ByVal value As SomethingChangedHandler)
If value.Method.IsPublic AndAlso _
(value.Method.DeclaringType.IsSerializable OrElse value.Method.IsStatic) Then
mSomethingChanged Serializable = _
DirectCast(System.Delegate.Combine( _
mSomethingChanged Serializable, value), SomethingChangedHandler)
Else
mSomethingChangedNonSerializable = _
DirectCast(System.Delegate.Combine( _
mSomethingChangedNonSerializable, value), SomethingChangedHandler)
End If
End AddHandler
RemoveHandler(ByVal value As SomethingChangedHandler)
If value.Method.IsPublic AndAlso _
(value.Method.DeclaringType.IsSerializable OrElse value.Method.IsStatic) Then
mSomethingChangedSerializable = DirectCast( _
System.Delegate.Remove( mSomethingChangedSerializable, value), SomethingChangedHandler)
Else
mSomethingChangedNonSerializable = DirectCast( _
System.Delegate.Remove( mSomethingChangedNonSerializable, value), SomethingChangedHandler)
End If
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal ausloeser As Object)
If mSomethingChangedNonSerializable IsNot Nothing Then
mSomethingChangedNonSerializable.Invoke(sender, ausloeser)
End If
If mSomethingChangedSerializable IsNot Nothing Then
mSomethingChangedSerializable.Invoke(sender, ausloeser)
End If
End RaiseEvent
End Event
Public Sub ThrowSomethingChangedEvent(ByVal reason As Object)
RaiseEvent SomethingChanged(Me, reason )
End Sub
End Class
As you can see the implementation seems pretty like the PropertyChanged event in the CSLA, but where are my mistakes?
Thank You for any help and greetings,
Mats
Mats replied on Wednesday, October 21, 2009
None additional information:
By removing the handler before ResetBindings and add the handler again afterwards, the problem is also gone.
But the question is:
What is the difference between the PropertyChanged event and my one or in the implementation of them because the PropertyChanged event does not need to be removed and added again?
Greetings,
Mats
RockfordLhotka replied on Wednesday, October 21, 2009
You could try simplifying your code. There's typically no reason to have the serializable delegate field at all. In fact, I've often thought about changing the CSLA code to remove the serializable delegate for all my events - but I haven't because of the if-it's-not-broke-don't-fix-it rule :)
But it turns out that serialization loses even the serializable event hookups, so there's no value in having the delegate be serializable. Maybe removing it (and all the checking code in your add/remove blocks) would fix the issue?
Mats replied on Friday, October 23, 2009
Hello Rockfoird !
Thank you for replying to my problem.
Using the custom event there has to be a public delegate that unfortunately cannot be marked as <NonSerialized()>.
So I tried out what you wrote by removing mSomethingChangedSerializable and it's use in the AddHandler and RemoveHandler.
But that does not fix my problem, it's still the same.
Maybe I misunderstand you ?
Greeting,
Mats
RockfordLhotka replied on Friday, October 23, 2009
The delegate doesn’t matter when using a custom event, because
it is the backing field that gets serialized, and you should now have only one
NonSerialized backing field. So if you are still getting serialization issues
then something else must be going on.
Mats replied on Monday, October 26, 2009
You are right and after correcting a minor mistake now removing and adding of the Handler is no longer neccessary for the use of ResetBindings.
Thanks and have a nice day,
Mats
Copyright (c) Marimer LLC