2

I'm having some issues with converting a custom event from vb.net to c#, I have no experience of vb.net really, and i have even less experience with these custom events, the rest of the application was converted without much issue, however this one has me stuck. The converters that i have used (both paid and free) have all failed to produce usable code.

VB.net code:

<NonSerialized()> Private _objNonSerializablePropertyChangedHandlers As New System.ComponentModel.EventHandlerList

'''' <summary> 
'''' Raised when a public property of this object is set. 
'''' </summary> 
Public Custom Event PropertyChanged As PropertyChangedEventHandler Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    AddHandler(ByVal value As PropertyChangedEventHandler)
        Me.NonSerializablePropertyChangedHandlers.AddHandler(STR_PROPERTYCHANGEDEVENT, value)
    End AddHandler
    RemoveHandler(ByVal value As PropertyChangedEventHandler)
        Me.NonSerializablePropertyChangedHandlers.RemoveHandler(STR_PROPERTYCHANGEDEVENT, value)
    End RemoveHandler
    RaiseEvent(ByVal sender As Object, ByVal e As PropertyChangedEventArgs)

        Dim obj As PropertyChangedEventHandler = TryCast(Me.NonSerializablePropertyChangedHandlers(STR_PROPERTYCHANGEDEVENT), PropertyChangedEventHandler)

        If obj IsNot Nothing Then
            obj.Invoke(sender, e)
        End If

    End RaiseEvent

the best i have managed to produce in c# is the following:

C#

[NonSerialized()]
private System.ComponentModel.EventHandlerList _objNonSerializablePropertyChangedHandlers = new System.ComponentModel.EventHandlerList();

public event PropertyChangedEventHandler PropertyChanged
{
    add
    {
        this.NonSerializablePropertyChangedHandlers.AddHandler(STR_PROPERTYCHANGEDEVENT, value);
    }
    remove
    {
        this.NonSerializablePropertyChangedHandlers.RemoveHandler(STR_PROPERTYCHANGEDEVENT, value);
    }
}

protected void OnPropertyChanged(string strPropertyName)
{
    EventHandler handler = this.PropertyChanged;
    if (handler != null)
    {
        handler.Invoke(this, new PropertyChangedEventArgs(strPropertyName));
        //PropertyChanged(this, new PropertyChangedEventArgs(strPropertyName));
    }
}

However this throws an error "The event 'CardBase.PropertyChanged' can only appear on the left hand side of += or -="

on the line : EventHandler handler = this.PropertyChanged;

As i'm not 100% on what the above code is doing, im struggling to fix this myself, I would be very grateful is someone could assist on this.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
Ben
  • 1,291
  • 2
  • 15
  • 36
  • That **should** compile... – It'sNotALie. Jun 10 '13 at 10:47
  • Not totally related to your question, but you can prevent a race condition by using the Interlocked.CompareExchange pattern to obtain your event handler. – Gayot Fow Jun 10 '13 at 10:53
  • @newStackExchangeInstance: Why do you say that? It certainly appears to be a valid compiler error... – Chris Jun 10 '13 at 10:53
  • @Chris The line he mentioned looks valid... maybe he should've put `PropertyChangedEventHandler` instead of `EventHandler`, but still. – It'sNotALie. Jun 10 '13 at 10:55
  • @newStackExchangeInstance: Did you read the error it gives? I can't quote you a compiler reference for where that is but if it empirically doesn't work then saying it should without any more information isn't very helpful. – Chris Jun 10 '13 at 11:02
  • @Chris I've read the error. The only thing I can think of is that the code isn't actually in his class... – It'sNotALie. Jun 10 '13 at 11:02
  • Are you SURE this is in the same class as the event, @OP? – It'sNotALie. Jun 10 '13 at 11:28
  • @newStackExchangeInstance: Ah, it looks like LinqPad (that I was testing with) probably does strange things with scope. What I hadn't realised (untili you encouraged me to research) is that you should be able to use it on the right hand side if the code is in the same class as the event definition (or something). I've not tested it elsewhere but I've concluded that LinqPad may well have let me down as a test bed today. :) – Chris Jun 10 '13 at 11:39
  • @newStackExchangeInstance Yes i'm 100% it is in the same class, I'm glad i'm not the only one who looked at the code and thought it should work. The answer below clears it up nicely however. Thanks for your input tho! EDIT: Also, i actually tried updating the code with PropertyChangedEventHandler, but i decided to post the code exactly as the converters spat it out for clarity sake. – Ben Jun 10 '13 at 12:49

1 Answers1

2

change this code

protected void OnPropertyChanged(string strPropertyName)
{
    EventHandler handler = this.PropertyChanged;
    if (handler != null)
    {
        handler.Invoke(this, new PropertyChangedEventArgs(strPropertyName));
    }
}

to

protected void OnPropertyChanged(string strPropertyName)
{
    var handler =
       this.NonSerializablePropertyChangedHandlers[STR_PROPERTYCHANGEDEVENT]
           as EventHandler;

    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(strPropertyName));
    }
}

reference -event- can only appear on the left hand side of += or -=

Community
  • 1
  • 1
Jürgen Steinblock
  • 30,746
  • 24
  • 119
  • 189
  • That wasn't where his error came from, it came from the top line. – It'sNotALie. Jun 10 '13 at 11:03
  • `EventHandler handler = this.PropertyChanged;` will still throw the exact same compiler warning surely... – Chris Jun 10 '13 at 11:03
  • You're right. Overlooked it. Anyway I updated the solution. I am guessing the automatic events have some compiler magic happening. Since you are creating an explicit event, you have to access the backing store itself. Btw. the VB.NET code already does this. – Jürgen Steinblock Jun 10 '13 at 11:14
  • Hey, thanks for the reply that did the job, i must admit i didnt have a full understanding of what this code did when looking through the vb.net code. Thanks again! – Ben Jun 10 '13 at 12:48
  • FYI: If you don't specify add / remove the compiler generates some code behind the scenes to make it thread safe http://stackoverflow.com/questions/15646155/decompiled-assembly-unusual-code which includes a backing variable. Your code introduces a EventHandlerList as a backing variable for multiple EventHandlers for whatever reason. – Jürgen Steinblock Jun 10 '13 at 13:19