Arman
Arman

Reputation: 1442

What am I doing wrong? - Visual Basic Events

I know that my problem is simple, but I cannot figure out what is wrong with my code. I have this Head First C# book, and I converted the code in VB.NET. I expected that the catches subroutine of Pitcher class will be called after I clicked a button in my form. But nothing happens.

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim myBall As New Ball
        Dim pitcher As New Pitcher
        myBall.OnBallInPlay(New BallEventArgs(10, 20))
    End Sub
End Class

Public Class Ball
    Public Event BallInPlay(ByVal sender As Object, ByVal e As BallEventArgs)
    Public Sub OnBallInPlay(ByVal e As BallEventArgs)
        RaiseEvent BallInPlay(Me, e)
    End Sub
End Class

Public Class BallEventArgs
    Inherits EventArgs
    Dim trajectory As Integer
    Dim distance As Integer
    Public Sub New(ByVal trajectory As Integer, ByVal distance As Integer)
        Me.trajectory = trajectory
        Me.distance = distance
    End Sub
End Class

Public Class Pitcher
    Public WithEvents mySender As Ball

    Public Sub catches(ByVal sender As Object, ByVal e As EventArgs) Handles mySender.BallInPlay
        MessageBox.Show("Pitcher: ""I catched the ball!""")
    End Sub
End Class

After invoking Ball.OnBallInPlay, Pitcher.catches shall listen. Isn't it, or am I missing something obvious and important?

Upvotes: 1

Views: 129

Answers (2)

Chris
Chris

Reputation: 8647

You need to connect the MyBall event to the pitcher.catches Method. Since the Myball is declared in the method you can't use the WithEvents keyword.

To connect the handler at runtime you use AddHandler.

Dim myBall As New Ball
Dim pitcher As New Pitcher
AddHandler myBall.BallInPlay, AddressOf pitcher.catches
myBall.OnBallInPlay(New BallEventArgs(10, 20))

To disconnect the handler you use RemoveHandler.

RemoveHandler myBall.BallInPlay, AddressOf pitcher.catches

EDIT

I just understood the problem/missing part. You just need to define the Pitcher.MySender since:

  • it is declared with WithEvents keyword
  • and you already invoke the catches method via Handles mySender.BallInPlay

    Dim myBall As New Ball
    Dim pitcher As New Pitcher
    pitcher.mySender = myBall
    myBall.OnBallInPlay(New BallEventArgs(10, 20))
    

Upvotes: 2

Alex Gittemeier
Alex Gittemeier

Reputation: 5373

You define pitcher, but you never use it:

Dim pitcher As New Pitcher

doesn't do anything, therefore, the catches subroutine can never be called as there are no instances of ball.

Additionally, mySender is never instantiated and mySender and myBall refer to different references to a Ball

Upvotes: 1

Related Questions