Solved

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

Posted on 2014-01-31
4
569 Views
Last Modified: 2014-02-03
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
Comment
Question by:PeterFrb
  • 2
4 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 39826258
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
 
LVL 16

Accepted Solution

by:
SriVaddadi earned 500 total points
ID: 39829661
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
 

Author Comment

by:PeterFrb
ID: 39830357
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
 

Author Closing Comment

by:PeterFrb
ID: 39830361
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

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now