Problem with own Event in derived BusinessBase and ResetBindings on a form

Problem 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 m
SomethingChangedNonSerializable As SomethingChanged Handler
    Private m
SomethingChangedSerializable 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
                    m
SomethingChanged Serializable = _
                        DirectCast(System.Delegate.Combine( _
                            m
SomethingChanged Serializable, value), SomethingChangedHandler)
                Else
                    m
SomethingChangedNonSerializable = _
                        DirectCast(System.Delegate.Combine( _
                            m
SomethingChangedNonSerializable, 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( m
SomethingChangedSerializable, value), SomethingChangedHandler)
                Else
                    m
SomethingChangedNonSerializable = DirectCast( _
                        System.Delegate.Remove( m
SomethingChangedNonSerializable, value), SomethingChangedHandler)
                End If
            End RemoveHandler

            RaiseEvent(ByVal sender As Object, ByVal ausloeser As Object)
                If m
SomethingChangedNonSerializable IsNot Nothing Then
                    m
SomethingChangedNonSerializable.Invoke(sender, ausloeser)
                End If
                If m
SomethingChangedSerializable IsNot Nothing Then
                    m
SomethingChangedSerializable.Invoke(sender, ausloeser)
                End If
            End RaiseEvent
    End Event

    Public Sub Throw
SomethingChangedEvent(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