AddHandler vs Handles

CJLeit

Active member
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 its friend RemoveHandler) allow you to control this at run time and even add event handles to instances that are created during the programs 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# doesnt even have an equivalent construct. Given this, it is not surprising there will be some scenarios where Handles wont 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 dont 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 doesnt even come close :)
 
Re: Handles is just a concise AddHandler

Its 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:

Code:
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. Im 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 youll need something like this:

Code:
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 forms 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 youll need something like this:

Code:
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. Im 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 dont 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 wasnt 100% sure.

I dont 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 its 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 by a moderator:
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 dont 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 its 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...
 

Similar threads

Back
Top