• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 608
  • Last Modified:

VB.Net: Genericizing a RemoveHandler via a delegate to a subroutine

I've created a sample of the code that very well shows what I'm trying to do.  In my production code, I will have a subroutine in a class module that changes the value of a control via code, in which case, I do not want the firing of my event handler, which checks on the validity of an entry.  I'm not quite sure how to implement this, but I've set it up a test-case scenario below, in which I've experimented with the desired implementation.  My form has a single button and a checkbox; and in my test, the code changes the textbox value; and I do not want the firing of the event, which, in this case, will generate a pop-up message.

When using the code in the form shown below, my error is this:
__Test_AddressOf.Handler' cannot be converted to 'System.EventHandler'.

Open in new window


When I change it to "RemoveHandler chkTest.CheckedChanged, AddressOf UseHandler", then I get this error:
'AddressOf' operand must be the name of a method (without parentheses).

Open in new window


I'm guessing some experts out there have figured out how to solve this problem!  Thanks, in advance.  ~Peter Ferber


Public Class __Test_AddressOf
    Public Delegate Function TestDelegate(ByVal iFirst As Integer, ByVal iSecond As Integer) As Long
    Public Delegate Sub Handler(ByVal sender As System.Object, ByVal e As System.EventArgs)

    Private Sub MenuItemStartTests_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemStartTests.Click
        Dim iFirst As Integer = 5
        Dim iSecond As Integer = 7
        MsgBox( _
            iFirst & "; " & iSecond & ": Multiplied = " & RunTest(5, 7, AddressOf Multiplier, AddressOf chkTest_CheckedChanged) & "; Added = " & RunTest(5, 7, AddressOf Adder, AddressOf chkTest_CheckedChanged))
    End Sub

    Private Function RunTest(ByVal iFirst As Integer, ByVal iSecond As Integer, ByVal testFunction As TestDelegate, ByVal UseHandler As Handler) As Long
        'Attempt to remove the handler before I change the checkbox.  Objective is not to see the message box "Logged Change!".
        RemoveHandler chkTest.CheckedChanged, UseHandler
        chkTest.Checked = (Not chkTest.Checked)

        RunTest = testFunction(iFirst, iSecond)
    End Function

    Private Function Multiplier(ByVal iFirst As Integer, ByVal iSecond As Integer) As Long
        Multiplier = iFirst * iSecond
    End Function

    Private Function Adder(ByVal iFirst As Integer, ByVal iSecond As Integer) As Long
        Adder = iFirst + iSecond
    End Function


    Private Sub chkTest_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkTest.CheckedChanged
        MsgBox("Logged Change!")
    End Sub
End Class

Open in new window

0
PeterFrb
Asked:
PeterFrb
  • 2
1 Solution
 
Bob LearnedCommented:
I believe that you can pass the argument as EventHandler, not the delegate type.

http://social.msdn.microsoft.com/Forums/vstudio/en-US/09b141c8-6752-43e7-8555-8755e0a04a63/passing-addressof-as-a-parameter-to-a-subroutine

Option Strict On
Option Explicit On
Option Infer Off

Public Class Form1

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim evHndlr As EventHandler
    evHndlr = AddressOf Button1_Click

    Call SomeMethod(evHndlr)

  End Sub

  Public Sub SomeMethod(ByVal evntHndlr As EventHandler)

    MessageBox.Show("Hi there!!")

  End Sub

End Class

Open in new window

0
 
SriVaddadiCommented:
Try this

Public Class __Test_AddressOf
    Public Delegate Function TestDelegate(ByVal iFirst As Integer, ByVal iSecond As Integer) As Long
    Public Delegate Sub Handler(ByVal sender As System.Object, ByVal e As System.EventArgs)

    Private Sub MenuItemStartTests_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemStartTests.Click
        Dim iFirst As Integer = 5
        Dim iSecond As Integer = 7
        MsgBox( _
            iFirst & "; " & iSecond & ": Multiplied = " & RunTest(5, 7, AddressOf Multiplier, chkTest_CheckedChanged) & "; Added = " & RunTest(5, 7, AddressOf Adder, AddressOf chkTest_CheckedChanged))
    End Sub

    Private Function RunTest(ByVal iFirst As Integer, ByVal iSecond As Integer, ByVal testFunction As TestDelegate, ByVal UseHandler As Handler) As Long
        'Attempt to remove the handler before I change the checkbox.  Objective is not to see the message box "Logged Change!".
        RemoveHandler chkTest.CheckedChanged, AddressOf UseHandler
        chkTest.Checked = (Not chkTest.Checked)

        RunTest = testFunction(iFirst, iSecond)
    End Function

    Private Function Multiplier(ByVal iFirst As Integer, ByVal iSecond As Integer) As Long
        Multiplier = iFirst * iSecond
    End Function

    Private Function Adder(ByVal iFirst As Integer, ByVal iSecond As Integer) As Long
        Adder = iFirst + iSecond
    End Function


    Private Sub chkTest_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkTest.CheckedChanged
        MsgBox("Logged Change!")
    End Sub
End Class
0
 
PeterFrbWeb development, Java scripting, Python TrainingAuthor Commented:
I tried your code, and there were a couple of issues with it, which I actually worked out.  Although my code recognized the word "Handler", the process would only work if I used "System.EventHandler"; and, in this case, I use the object, not the address of the object.  Not sure why your version did not work exactly on mine; but the exercise has been useful and fruitful, and I'll give you the credit on this question.  ~Peter


Public Class _Test_AddressOf_V2
    Public Delegate Function TestDelegate(ByVal iFirst As Integer, ByVal iSecond As Integer) As Long
    Public Delegate Sub Handler(ByVal sender As System.Object, ByVal e As System.EventArgs)

    Private Sub MenuItemStartTests_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemStartTests_V3.Click
        Dim iFirst As Integer = 5
        Dim iSecond As Integer = 7
        MsgBox( _
            iFirst & "; " & iSecond & ": Multiplied = " & RunTest(5, 7, AddressOf Multiplier, AddressOf chkTest_CheckedChanged) & "; Added = " & RunTest(5, 7, AddressOf Adder, AddressOf chkTest_CheckedChanged))
    End Sub

    Private Function RunTest(ByVal iFirst As Integer, ByVal iSecond As Integer, ByVal testFunction As TestDelegate, ByVal UseHandler As System.EventHandler) As Long
        'Attempt to remove the handler before I change the checkbox.  Objective is not to see the message box "Logged Change!".
        RemoveHandler chkTest_V2.CheckedChanged, UseHandler
        chkTest_V2.Checked = (Not chkTest_V2.Checked)

        RunTest = testFunction(iFirst, iSecond)
    End Function

    Private Function Multiplier(ByVal iFirst As Integer, ByVal iSecond As Integer) As Long
        Multiplier = iFirst * iSecond
    End Function

    Private Function Adder(ByVal iFirst As Integer, ByVal iSecond As Integer) As Long
        Adder = iFirst + iSecond
    End Function


    Private Sub chkTest_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkTest_V2.CheckedChanged
        MsgBox("Logged Change!")
    End Sub

End Class

Open in new window

0
 
PeterFrbWeb development, Java scripting, Python TrainingAuthor Commented:
Not the exactly right answer for my setup; but that may be due to a reference quirk.  Am happy to have two working solutions, so that more people get good results from the question.  Many thanks, ~Peter
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now