2

I've been trying figure out how to add a handler to a method using Codedom, but am not getting very far.

The method I want to reproduce via Codedom is:

Private Sub Startup() Handles btnStart.Click
    ''# Do work
End Sub

The method is easy enough to create with:

Dim StartupMethod As New CodeMemberMethod
StartupMethod.Name = "Startup"
StartupMethod.Attributes = MemberAttributes.Private

But I can't figure out how to add the Handles btnStart.Click. I've looked at CodeAttachEventStatement, but this I don't believe it can do a Handles on a method.

Does anyone know how to achieve this?

EDIT: The solution below works for VB, but does not work for C# because the handler is looking to handle an event rather than a method.

Todd Main
  • 28,951
  • 11
  • 82
  • 146

1 Answers1

3

Handles is just a syntactic sugar vb.net offers you for your convenience. Under the hood it is converted to:

AddHandler btnStart.Click, AddressOf Startup

So I think it won't be possible. You should try to use the CodeAttachEvent statement instead

http://msdn.microsoft.com/en-us/library/system.codedom.codeattacheventstatement.aspx

Another possibility is to use CodeSnippetTypeMember() as described here

Workaround for VB.NET partial method using CodeDom?

Community
  • 1
  • 1
Jürgen Steinblock
  • 30,746
  • 24
  • 119
  • 189
  • so you're saying I should use the above to initialize the handler, like in constructor `New()` statement? – Todd Main Aug 15 '10 at 14:21
  • +1, yes, generate the constructor and use CodeAttachEventStatement. – Hans Passant Aug 15 '10 at 15:01
  • Yes, I haven't done it yet, but I bet you would find AddHandler methods in the New() constructor if you inspect your `Handles ...` code in reflector. – Jürgen Steinblock Aug 15 '10 at 15:30
  • Got that, it's working, unfortunately it now produces a problem when using a CSharp provider. It produces code like `btnStart.Click += new System.EventHandler(this.Startup);` when it should just produce `btnStart.Click += this.Startup;` - I think the error is related to the fact that the method isn't declared an event. – Todd Main Aug 15 '10 at 15:54
  • 1
    In C# it's supposed to be btnStart.CLick += new System.EventHandler(this.Startup) so I dont think that's the cause of your error Otaku – PsychoCoder Aug 15 '10 at 17:02
  • @PsychoCoder: For this: `private void Startup(){}`? – Todd Main Aug 15 '10 at 17:13
  • Found this interesting article about how the VB.Net `Handles` keyword is translated internally http://codebetter.com/blogs/peter.van.ooijen/archive/2005/08/02/130194.aspx It also removes an existing handler if necesarry. – Jürgen Steinblock Aug 15 '10 at 18:11
  • @Otaku, the signature of your Startup Method should be `Private Sub Startup(ByVal sender as Object, ByVal e as System.EventArgs)`. VB.Net allows you to add handlers to a method with an empty signature since VS 2008. But I suppose that is syntactic sugar, too and internally a method with the correct signature is added that only calls the `Startup()` method. You can't do that in C# – Jürgen Steinblock Aug 15 '10 at 18:15
  • @SchlaWiener: I left out the arguments in the method just for simplicity and less code. I'm looking at the link you posted above, it's really interesting. I'm still trying to wrap my head around how C# does things and why it's not explicit. Mostly, I'm just trying to get Codedom to do the same thing in both languages. More soon after I've researched this some more. – Todd Main Aug 15 '10 at 22:39
  • @Otaku - I always use the right signature from start. It makes it more readable since the `sender, e` signature already shows in which context this method is used without further comments. If you need the `sender` or `e` later, you have to refactor your code anyway. And since you want your code to be compatible with c# and vb.net you wont have a choise. – Jürgen Steinblock Aug 16 '10 at 07:25