Warning on RemoveHandler for UserControl event
-
Saturday, February 27, 2010 12:07 AM
Using VB2008 Express I'm getting the following warning on a RemoveHandler statement and subsequent issues since the event is still hooked.
Warning 1 The 'AddressOf' expression has no effect in this context because the method argument to 'AddressOf' requires a relaxed conversion to the delegate type of the event. Assign the 'AddressOf' expression to a variable, and use the variable to add or remove the method as the handler.
I defined a custom control that inherits from System.Windows.Forms.UserControl.
The custom control contains a ListBox (among other things).
In the custom control .vb I define an event to propagate the SelectedIndexChanged event from the ListBox as follows:Public Event cListBox_SelectedIndexChanged as EventHandler
Also in the custom control .vb is an event handler for the ListBox as follows:
Private Sub ListBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox.SelectedIndexChanged RaiseEvent cListBox_SelectedIndexChanged(sender, e) End SubIn the form that uses this control I define an event handler as follows:
Private Sub cListBox_SelectedIndexChanged(ByVal sender As ListBox, ByVal e As System.EventArgs) ... End Sub
I hook the event with an AddHandler statement as follows:
AddHandler CustomControl.cListBox_SelectedIndexChanged, _ AddressOf cListBox_SelectedIndexChanged
I try to unhook the event with the following:RemoveHandler CustomControl.cListBox_SelectedIndexChanged, _ AddressOf cListBox_SelectedIndexChangedHowever, I get a green squiggly underline on the above and the warning mentioned at the top of the thread. It also does not unhook the event as the warning message stated.
I'm sure the warning message is well thought out but I don’t know what it means or how to correct the issue. What is a delegate type of the event and how is the AddressOf expression assigned to a variable?
I've tried both of the following, neither of which will compile.Dim eha = AddressOf cListBox_SelectedIndexChanged Dim eha As [Delegate] = AddressOf cListBox_SelectedIndexChanged
Any help would be appreciated.
Thanks,
Eric
Answers
-
Tuesday, March 02, 2010 10:09 AM
Hi again Eric,
If you mean you want to assign handler and remove handler via delegate, then you can look into the following sample. The key point here is that you need to declare an event with a delegate type instead of a signature.
Public Class Form1 Public Delegate Sub MessageHandler() Private myMessageHandler As MessageHandler Private evObj As MyCustomEventClass Private Sub ShowMessage() MessageBox.Show("My Custom Event Raised") End Sub Class MyCustomEventClass Public Event MyCustomEvent As MessageHandler Public Sub RaiseMyCustomEvent() RaiseEvent MyCustomEvent() End Sub End Class 'add handler Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click myMessageHandler = New MessageHandler(AddressOf ShowMessage) evObj = New MyCustomEventClass AddHandler evObj.MyCustomEvent, myMessageHandler End Sub 'remove handler Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click RemoveHandler evObj.MyCustomEvent, myMessageHandler End Sub 'test Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click evObj.RaiseMyCustomEvent() End Sub End ClassRegards
Jeff Shan
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Proposed As Answer by Jeff Certain Tuesday, May 04, 2010 4:09 PM
- Marked As Answer by Eric-67220 Wednesday, May 05, 2010 12:04 AM
-
Tuesday, March 02, 2010 3:22 PM
Jeff,
Thanks so much for putting the time into demonstrating the use of delegates in event handling. I pasted your above code into a WindowsForms project with three buttons on the form and it runs. I moved the evObj assignment from the Button1_Click event to the Form_Load event so that if Button2 or Button3 is clicked prior to Button1 the NullReferenceException error will be avoided. I need to study it some more to completely understand it. It is more complex than what you showed in your first post and at the moment I’m not sure what the added complexity provides.
I’m all for keeping things as simple as possible. What I am doing is essentially the same as what you have in your first example. One exception is that the event handling procedure in the main form that I am hooking and trying to unhook has it’s sender parameter declared as ListBox rather than Object whereas you use DirectCast to convert Object to Button within the procedure in order to access the .Name property.
In studying the MSDN information on Delegates and the relaxed conversion that was added in VB2008 I suspect that the widening or narrowing that may be involved between Object (wide) and ListBox (narrow) may be the issue the warning is objecting to. The other difference is that my user controls are referenced using an array and I saw some things mentioned in those discussions that could not be done with arrays.
...
Just changed the type of the sender parameter to Object in the event handling procedure and this fixed the warning issue.Thanks again,
Eric
- Marked As Answer by Eric-67220 Tuesday, March 02, 2010 3:23 PM
All Replies
-
Saturday, February 27, 2010 12:52 AMYou need to create the delegate type befoer you can declare a variable of that type and use it as a delegate.
Private Delegate Sub eha(ByVal sender As Object, ByVal e As System.EventArgs)
dim MYeha as eha = AddressOf cListBox_SelectedIndexChanged -
Saturday, February 27, 2010 4:43 PM
Acamar,
First, thanks for the thoughtful reply.
I added the two lines you gave me to create the delegate type eha and the delegate instance MYeha.
I then changed the RemoveHandler statement as follows:RemoveHandler CustomControl.cListBox_SelectedIndexChanged, AddressOf MYeha
I get the following error:
Error 1 'AddressOf' operand must be the name of a method (without parentheses).
Thinking the MYeha delegate is an AddressOf I made the following change:RemoveHandler CustomControl.cListBox_SelectedIndexChanged, MYeha
I get the following error:
Error 1 Value of type 'Project.Form.eha' cannot be converted to 'System.EventHandler'.
So it seems there is more I have to learn.
I'm studying the following on the MSDN.
Delegates in Visual Basichttp://msdn.microsoft.com/en-us/library/ms172879.aspx
My form adds and removes one or more of the custom controls at run time and I add and remove the event handlers as the custom controls are added and removed. I also need to remove certain handlers for child control events passed up through the custom control when loading values into the child controls from code in the form (unlike when the user is selecting values with the child controls).Thanks again,
Eric -
Tuesday, March 02, 2010 8:35 AM
Hi Eric,
According to the message you can see that you need to make sure the argument is a method name.
Here is a simple example
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load AddHandler Button1.Click, AddressOf MyClick End Sub Private Sub MyClick(ByVal sender As System.Object, ByVal e As System.EventArgs) MessageBox.Show(DirectCast(sender, Button).Name & " Clicked") End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click RemoveHandler Button1.Click, AddressOf MyClick End Sub End ClassHope this helps
Regards
Jeff Shan
Please remember to mark the replies as answers if they help and unmark them if they provide no help. -
Tuesday, March 02, 2010 10:09 AM
Hi again Eric,
If you mean you want to assign handler and remove handler via delegate, then you can look into the following sample. The key point here is that you need to declare an event with a delegate type instead of a signature.
Public Class Form1 Public Delegate Sub MessageHandler() Private myMessageHandler As MessageHandler Private evObj As MyCustomEventClass Private Sub ShowMessage() MessageBox.Show("My Custom Event Raised") End Sub Class MyCustomEventClass Public Event MyCustomEvent As MessageHandler Public Sub RaiseMyCustomEvent() RaiseEvent MyCustomEvent() End Sub End Class 'add handler Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click myMessageHandler = New MessageHandler(AddressOf ShowMessage) evObj = New MyCustomEventClass AddHandler evObj.MyCustomEvent, myMessageHandler End Sub 'remove handler Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click RemoveHandler evObj.MyCustomEvent, myMessageHandler End Sub 'test Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click evObj.RaiseMyCustomEvent() End Sub End ClassRegards
Jeff Shan
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Proposed As Answer by Jeff Certain Tuesday, May 04, 2010 4:09 PM
- Marked As Answer by Eric-67220 Wednesday, May 05, 2010 12:04 AM
-
Tuesday, March 02, 2010 3:22 PM
Jeff,
Thanks so much for putting the time into demonstrating the use of delegates in event handling. I pasted your above code into a WindowsForms project with three buttons on the form and it runs. I moved the evObj assignment from the Button1_Click event to the Form_Load event so that if Button2 or Button3 is clicked prior to Button1 the NullReferenceException error will be avoided. I need to study it some more to completely understand it. It is more complex than what you showed in your first post and at the moment I’m not sure what the added complexity provides.
I’m all for keeping things as simple as possible. What I am doing is essentially the same as what you have in your first example. One exception is that the event handling procedure in the main form that I am hooking and trying to unhook has it’s sender parameter declared as ListBox rather than Object whereas you use DirectCast to convert Object to Button within the procedure in order to access the .Name property.
In studying the MSDN information on Delegates and the relaxed conversion that was added in VB2008 I suspect that the widening or narrowing that may be involved between Object (wide) and ListBox (narrow) may be the issue the warning is objecting to. The other difference is that my user controls are referenced using an array and I saw some things mentioned in those discussions that could not be done with arrays.
...
Just changed the type of the sender parameter to Object in the event handling procedure and this fixed the warning issue.Thanks again,
Eric
- Marked As Answer by Eric-67220 Tuesday, March 02, 2010 3:23 PM

