Question

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?

Was it helpful?

Solution

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))
    

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top