user1986815
user1986815

Reputation:

Strange WithEvents thing

Very simple case.
A Form Class inside a Button that triggers a MsgBox

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MessageBox.Show("TEST")
    End Sub
End Class

then I create a new class Class1 and move the Sub Button1_Click to that class

Public Class Form1

End Class
Public Class Class1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Form1.Button1.Click
        MessageBox.Show("TEST")
    End Sub
End Class

And I get a Failure

Failure BC30506 Handles clause requires a WithEvents variable that is defined in the containing type or one of its base types.

then I modified like this:

Public Class Class1
    Public WithEvents Form1.Button As EventThrower()
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Form1.Button1.Click
        MessageBox.Show("TEST")
    End Sub
End Class

And now I get 2 Failures

Error BC30412 ' WithEvents ' variables must have an as clause.

Error BC31412 'Handles' in classes must specify a WithEvents variable, 'MyBase', 'MyClass' or 'Me' qualified with a single identifier.

Can Somebody explain me this in a simple way ?

UPDATE 1:
The Solution coming from Visual Vincent removes the Error but by clicking the Button1 on Form1 the MessageBox gets not fired, so practically its not working.

Public Class Class1
    Public WithEvents Button1 As Button = Form1.Button1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MessageBox.Show("TEST")
    End Sub
End Class

How can I get the Button1 on Form1 fired from within the Class1 ?

Upvotes: 0

Views: 794

Answers (3)

Jim Hewitt
Jim Hewitt

Reputation: 1792

Try this:

Public Class Form1

'Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'    MessageBox.Show("TEST")
'End Sub

   Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      AddHandler Button1.Click, AddressOf Class1.ButtonClick
  End Sub

End Class

Public Class Class1

   Public Shared Sub ButtonClick(sender As Object, e As EventArgs)
      MessageBox.Show("Clicked from ButtonClick")
   End Sub

End Class

Upvotes: 3

Visual Vincent
Visual Vincent

Reputation: 18330

I don't know what an EventThrower is, but your variable declaration is invalid. After the access modifier (in this case Public) a name is expected, and names cannot contain dots.

I would suggest you do something like this instead:

Public Class Class1
    Public WithEvents Button1 As Button = Form1.Button1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MessageBox.Show("TEST")
    End Sub
End Class

To make this work without a class instance you can mark everything as Shared. EDIT: As I suspected you have to access the class at least once or else the handler won't get attached. Calling an empty method should suffice:

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Class1.Initialize()
    End Sub
End Class

Public Class Class1
    Public Shared WithEvents Button1 As Button = Form1.Button1
    Private Shared Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MessageBox.Show("TEST")
    End Sub

    Public Shared Sub Initialize()
    End Sub
End Class

Upvotes: 1

Fabio
Fabio

Reputation: 32463

but by clicking the Button1 on Form1 the MessageBox gets not fired, so practically its not working.

Public WithEvents Button1 As Button = Form1.Button1

Based on your code Form1 is a class. Where Form1.Button1 mean that class Form1 have static variable Button1.

Obviously you have Button1 in your Form1 class, which can be accessed only through instance of Form1. For getting right instance of Form1 you need pass that instance as parameter to Class1.

Then your code:

    Public WithEvents Form1.Button As EventThrower() 
  1. Name of variables cannot contain dot (as mentioned by @Visual Vincent)
  2. You can declare only individual variables—not arrays—with WithEvents.
    ... As EventThrower() is declaring array of type EventThrower

So you need change the line to be type of EventThrower

Public WithEvents MyEventThrower As EventThrower

Main problem of your code that you try use instance of button and handle it's Click event in another class, which not a good practice.

If you want move code of Click handler to the another class, do it with reverting dependency. Your Form will have dependency on class which contains logic

Public Class LogicClass
    Public Function ExecuteSomeLogicAndReturnValue() As String
        Return "TEST"
    End Sub
End Class

Public Class MyForm Inherits Form
    Private _Logic As New LogicClass()

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Me.MyButton.Click
        Dim value As String = _Logic.ExecuteSomeLogicAndReturnValue()
        MessageBox.Show(value)
    End Sub
End Class

Upvotes: 2

Related Questions