AddHandler vs Handles

CJLeit

Freshman
Joined
Feb 1, 2006
Messages
32
Why with some function do I have to use an AddHandler statment but with other I can create a function and use the handles statement? For example with the format event of a bound control you use the below statement but there is no way I know of to make a sub and use the Handles keywork.

Code:
AddHandler textBox.DataBindings("Text").Format, AddressOf FormatName

Thanks!
 
The Handles statement only works for things that are declared at design time and you always want the handler to be associated with the event.

AddHandler (and it's friend RemoveHandler) allow you to control this at run time and even add event handles to instances that are created during the program's execution.
 
Handles is just a concise AddHandler

Handles declarations cause the compiler to emit AddHandler equivalents within the constructor. Therefore Handles can be considered merely "syntactic sugar" - indeed, C# doesn't even have an equivalent construct. Given this, it is not surprising there will be some scenarios where Handles won't work.

In your case, it may be quite difficult for the compiler to infer that there is Binding object to listen to due to the fact that it is specified from a collection using a text string ("Text"). It may be that Handles simply cannot be used for objects which may not exist, and you are forced to use the equivalent AddHandler. Considering this is only one line of code, I don't see that it is much of an inconvenience.

Good luck :)

The Handles statement only works for things that are declared at design time and you always want the handler to be associated with the event.

It would be extremely counter-intuitive to do so, but I expect you could use RemoveHandler on an event which was added using Handles.
 
Re: Handles is just a concise AddHandler

It would be extremely counter-intuitive to do so, but I expect you could use RemoveHandler on an event which was added using Handles.

Just tried it and it turns out you can actually remove an event handler that was attached using the Handles keyword! counter-intuitive doesn't even come close :)
 
Re: Handles is just a concise AddHandler

It's counter-intuitive because VB.NET is doing the AddHandler and RemoveHandler for you... So one should use a 'WithEvents' variable and let the compiler take care of it for you, or explicitly use AddHandler and RemoveHandler yourself. But not both!

Paul Vick has a nice discussion of what VB is doing behind the scenes here:

http://www.panopticoncentral.net/archive/2004/08/03/1536.aspx


CJLeit,

I dont have an IDE in front of me, so I cannot test this, but if you really want to use the 'WithEvents' construct here, you should be able to. You should first create a static field somewhere, declaring the variable 'WithEvents' and typed as 'System.Windows.Forms.Binding':

Visual Basic:
Shared WithEvents MyTextBinding As System.Windows.Forms.Binding

After that you should be able to use the dropdown controls within Visual Studio to find your 'MyTextBinding' field and then choose the 'Format' event. The IDE will then create a stub for you.

(Or you probably can simply add 'Handles MyTextBinding.Format' to the end of your existing 'FormatName()' method. I'm not 100% sure of this, but my guess is that this would work.)

Ok, lastly, something has to set your MyTextBinding to actually hold an object. So somewhere in your code you'll need something like this:

Visual Basic:
MyTextBinding  = textBox.DataBindings("Text")

To be honest though, if you are comfortable using AddHandler and RemoveHandler, then doing so it probably more direct and clear. I would let the IDE/designer create 'WithEvents' and 'Handles' constructs for the form's controls, but otherwise, use whatever is cleaner and easier for you to use.

Hope this helps...
Mike
 
AddHandler during constructor

Ok, lastly, something has to set your MyTextBinding to actually hold an object. So somewhere in your code you'll need something like this:

Visual Basic:
MyTextBinding  = textBox.DataBindings("Text")

This approach involves declaring an additional variable as an event source and will work, but only if the variable is assigned to within the constructor, since the compiler emits the AddHandler calls at the end of the constructor.

If the variable were assigned to elsewhere, the event handlers would not be attached, unless of course the compiler emits AddHandler (and RemoveHandler) calls there too, which would seem slightly convoluted if true. Another quirk of VB I suppose.

(Or you probably can simply add 'Handles MyTextBinding.Format' to the end of your existing 'FormatName()' method. I'm not 100% sure of this, but my guess is that this would work.)

Yes you would be able to just add Handles MyTextBinding.Format to the existing FormatName method, since as far as the compiler is concerned the variable is no different to any other event source such as a control.

Good luck :cool:
 
Re: AddHandler during constructor

I don't have VB on this machine to test it, but I do believe that the Handles clause manages handlers outside the constructor. I personally think that this is more intuitive than convoluted. It is like associating a handler with a variable instead of an object, which can be quite a convinience as long as you understand what the code is doing.
 
Re: AddHandler during constructor

If the variable were assigned to elsewhere, the event handlers would not be attached, unless of course the compiler emits AddHandler (and RemoveHandler) calls there too, which would seem slightly convoluted if true. Another quirk of VB I suppose.
Actually, this is exactly what VB is doing. When a new object is set to the variable, extra code is emitted to release the old object via a 'RemoveHandler' call, then the new object is set, and then 'AddHandler' is called for the new object. This only occurs for variables declare 'WithEvents'. otherwise you can just do C#-style event handling by assigning the delegate directly.

Yes you would be able to just add Handles MyTextBinding.Format to the existing FormatName method, since as far as the compiler is concerned the variable is no different to any other event source such as a control.
Ok, this makes sense. I thought so, but I wasn't 100% sure.

I don't have VB on this machine to test it, but I do believe that the Handles clause manages handlers outside the constructor. I personally think that this is more intuitive than convoluted. It is like associating a handler with a variable instead of an object, which can be quite a convinience as long as you understand what the code is doing.
Yeah, I agree on both counts: it sounds convoluted, but using it is very smooth. In fact, the handshake between the variable declared 'WithEvents' and the event handler declared 'Handles VariableName.Eventname' is hard to beat. But it's really only good for object-event pairings that are relatively static. But this makes it perfect for constrols on a form and many other situations...

Again, Paul Vick has a very nice discussion of what VB is doing behind the scenes here:

http://www.panopticoncentral.net/archive/2004/08/03/1536.aspx

Mike
 
Last edited:
VB vs C# event handling

Actually, this is exactly what VB is doing. When a new object is set to the variable, extra code is emitted to release the old object via a 'RemoveHandler' call, then the new object is set, and then 'AddHandler' is called for the new object. This only occurs for variables declare 'WithEvents'. otherwise you can just do C#-style event handling by assigning the delegate directly.

I guess it just seems slightly convoluted coming from a C# (and Java) background where event handlers are obviously tied to the object, whereas the WithEvents pattern ties handlers to the variable and the compiler deals with the objects for you. In any case, I can see how it would be very convenient to have this behaviour and not have to worry about attaching and detaching events as you have to do in C#. It certainly makes sense when migrating from VB6 which works in a similar way.

I suppose I should have tested whether AddHandler and RemoveHandler are emitted when the variable is assigned to outside a constructor. I guess I don't like the fact that its not always obvious what is happening behind the scenes, but then again this is the nature of abstraction (which is what .Net is all about) and if it means the programmer does not need to worry about little details then this must be a good thing.

:)
 
Re: VB vs C# event handling

Yes, *generally* this stuff is a good thing. I think that both the VB and C# teams have mostly made excellent decisions in terms of trade-offs.

And it's not just VB that creates these artificial constructs behind the scenes. The things that come to mind that C# has implemented include:

(a) 'yield return' iterators that maintain state via pointers behind the scenes while externally implementing the IEnumerable interface

(b) Nullables, for which C# had to go through a lot of hurdles to achieve. C# had much more to do here than VB because VB makes some different assumptions with respect to value type auto-initialization than does C#, and, frankly, because C# took nullables further than did VB.

(c) Anonymous methods, which maintain state via the construction of hidden classes under the hood.

There must be many more examples like this, but this is what comes to the top of my head...
 
Back
Top