Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom events conversion issues #76

Open
VBAndCs opened this issue Jul 6, 2021 · 4 comments
Open

Custom events conversion issues #76

VBAndCs opened this issue Jul 6, 2021 · 4 comments

Comments

@VBAndCs
Copy link

VBAndCs commented Jul 6, 2021

The converter has serious issues with custom events. For example, this code:

		private static event SmallBasicCallback _buttonClicked;

		/// <summary>
		/// Raises an event when any button control is clicked.
		/// </summary>
		public static event SmallBasicCallback ButtonClicked
		{
			add
			{
				Controls._buttonClicked = null;
				_buttonClicked += value;
			}
			remove
			{
				_buttonClicked -= value;
			}
		}

is converted to:

             Private Shared Event _buttonClicked As SmallBasicCallback
        ''' <summary>
        ''' Raises an event when any button control is clicked.
        ''' </summary>
        Public Shared Custom Event ButtonClicked As SmallBasicCallback
            AddHandler(Value As SmallBasicCallback)
                Controls._buttonClicked = Nothing
                _buttonClicked += value
            End AddHandler
            RemoveHandler(Value As SmallBasicCallback)
                _buttonClicked -= value
            End RemoveHandler
            RaiseEvent(sender As Object, e As EventArgs)
            End RaiseEvent
        End Event

Which has many errors:

  1. Controls._buttonClicked = Nothing
  2. _buttonClicked += value
  3. _buttonClicked -= value
  4. RaiseEvent(sender As Object, e As EventArgs)

and there is a related error when using this code to raise the event in another place:
5. Controls._buttonClicked?.Invoke()

The correct code should be:

        Private Shared _buttonClicked As new EventHandlerList


        ''' <summary>
        ''' Raises an event when any button control is clicked.
        ''' </summary>
        Public Shared Custom Event ButtonClicked As SmallBasicCallback
            AddHandler(Value As SmallBasicCallback)
                Dim h = TryCast(_buttonClicked("ButtonClicked"), SmallBasicCallback)
                If h IsNot Nothing Then _buttonClicked.RemoveHandler("ButtonClicked", h)
                _buttonClicked.AddHandler("ButtonClicked", Value)
            End AddHandler

            RemoveHandler(Value As SmallBasicCallback)
                _buttonClicked.RemoveHandler("ButtonClicked", Value)
            End RemoveHandler

            RaiseEvent()
                Dim h = TryCast(_buttonClicked("ButtonClicked"), SmallBasicCallback)
                If h IsNot Nothing Then h.Invoke()
            End RaiseEvent
        End Event

and to raise the event:
'RaiseEvent ButtonClicked()'
Note: we use ButtonClicked not _buttonClicked, becuae I changed it from event to EventHandlerList. C# can set the event to null, but VB can't, and we must do it through the EventHandlerList.

Note: you can use one EventHandlerList to deal with all events in the class, as long as each event has a unique key. Say:
Private Shared Events As EventHandlerList

This is an example:

Class Foo
      Private Events As new EventHandlerList

        Public Custom Event KeyDown As SmallBasicCallback
            AddHandler(Value As SmallBasicCallback)
                Dim Key = NameOf(KeyDown)
                Dim h = TryCast(Events(Key), SmallBasicCallback)
                If h IsNot Nothing Then Events.RemoveHandler(Key, h)
                Events.AddHandler(Key, Value)
            End AddHandler

            RemoveHandler(Value As SmallBasicCallback)
                Events.RemoveHandler(NameOf(KeyDown), Value)
            End RemoveHandler

            RaiseEvent()
                Dim h = TryCast(Events(NameOf(KeyDown)), SmallBasicCallback)
                If h IsNot Nothing Then h.Invoke()
            End RaiseEvent
        End Event

        Public Custom Event KeyUp As SmallBasicCallback
            AddHandler(Value As SmallBasicCallback)
                Dim Key = NameOf(KeyUp)
                Dim h = TryCast(Events(Key), SmallBasicCallback)
                If h IsNot Nothing Then Events.RemoveHandler(Key, h)
                Events.AddHandler(Key, Value)
            End AddHandler

            RemoveHandler(Value As SmallBasicCallback)
                Events.RemoveHandler(NameOf(KeyUp), Value)
            End RemoveHandler

            RaiseEvent()
                Dim h = TryCast(Events(NameOf(KeyUp)), SmallBasicCallback)
                If h IsNot Nothing Then h.Invoke()
            End RaiseEvent
        End Event
End Class

Note that that this part in the AddHandler:

                Dim h = TryCast(Events(Key), SmallBasicCallback)
                If h IsNot Nothing Then Events.RemoveHandler(Key, h)

is not necessary unless C# sets the event to null. In my code, each event will have only one handler, but this is not the generic case, so, it there is no _event = bull in C#, omit this part.

@paul1956
Copy link
Owner

paul1956 commented Jul 7, 2021

@VBAndCs what is an EventHandlerList? I have reimplemented the conversion in version 5.0.1.21. Please provide feedback.

@paul1956 paul1956 closed this as completed Jul 7, 2021
@VBAndCs
Copy link
Author

VBAndCs commented Jul 7, 2021

EventHandlerList is used internally to store event handlers for normal events (you can get it via reflection if you need), and you should use it manually with custom events. It is defined in System.ComponentModel.

@paul1956 paul1956 reopened this Jul 9, 2021
@paul1956
Copy link
Owner

paul1956 commented Jul 9, 2021

@VBAndCs I will look at this more everything looks good except raising event and that is a big issue with current implementation.

@paul1956
Copy link
Owner

@VBAndCs I fixed a lot of it but there are still a few issues with raising events

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants