1

We're creating objects at runtime so before running the code doesn't know what object it is working with. We want to add an event handler to every TextBox which is created at runtime. But when we try AddHandler obj.Leave, AddressOf leaveControl the compiler won't run the program because "object doesn't have an event like Leave".

Is there a way to add an event handler to a object of unknown type?

Thanks :)

Dyrdek
  • 411
  • 4
  • 12
  • 33
  • show the code where you create your controls – Ric Oct 14 '15 at 12:13
  • Surely despite the fact that you're creating these objects at runtime you will have some idea that they will be of type TextBox. Given that that is the case then a simple if GetType(obj) returns you type = TextBox then you can add your addhandler as you then know you have a textbox in the obj variable which will possess the event that you want to handle. – Dom Sinclair Oct 14 '15 at 12:20
  • How can these things be unknown, if you are creating them? – Ňɏssa Pøngjǣrdenlarp Oct 14 '15 at 12:30
  • @Plutonix That's an extraordinarily good point! – Dom Sinclair Oct 14 '15 at 12:42

4 Answers4

3

VB.NET supports late binding to write dynamic code. That works well for properties and methods but not for events. Odd restriction, I don't know the technical reason for it. Short from it never having to be necessary in earlier versions of Basic where event binding was dynamic based on the method name, I suspect it has something to do with the WithEvents keyword.

The workaround is simple enough, you need to use Reflection. Like this:

    Dim obj As Object = New TextBox
    Dim evt = obj.GetType().GetEvent("Leave")
    evt.AddEventHandler(obj, New EventHandler(AddressOf leaveControl))
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

You do know it's a textbox, so cast it

AddHandler Ctype(obj,textbox).Leave, AddressOf leaveControl

Brnd
  • 31
  • 2
  • No you can't do that because as he states in his question the code doesn't know what object it is. He needs to test what type the object is first and then add the relevant add handler statement if it turns out to be a textbox. – Dom Sinclair Oct 14 '15 at 12:24
  • I tried it with a simple if-clause like `If TypeOf(obj) Is TextBox Then [...]` but that didn't work out. If this is what you meant Dom :/ – Dyrdek Oct 14 '15 at 12:28
  • That's what I meant yes, can you actually post your routine that isn't working. – Dom Sinclair Oct 14 '15 at 12:31
  • `If String.Compare(elementName, "object") = 0 Then obj = createObject(attributeValues(0)) If obj Is Nothing Then If TypeOf (obj) Is TextBox Then AddHandler obj.Leave, AddressOf leaveControl End If Return obj End If Endif` – Dyrdek Oct 14 '15 at 12:47
1

Without seeing your code for creating the controls, as @Dom suggests, you can check the type of control you are creating using the following (as an example for looking at textboxes only);

Dim tb As TextBox = TryCast(obj, TextBox)

If tb IsNot Nothing
    AddHandler tb.Leave, AddressOf leaveControl
End If

Again, this is just an illustration without knowing the full extent of what you are doing in the first place

Ric
  • 12,855
  • 3
  • 30
  • 36
  • Like I said in the other comment it didn't work out with the if-clause for some reason. First we are creating an `Dim ob As Object` then it gets a type like "TextBox" (depending on a XML file) with `Activator.CreateInstance(type)`. After that we want to add the handler, but even with a if-clause the compiler doesn't allow to run the code. – Dyrdek Oct 14 '15 at 12:31
  • How can I set the "TextBox" in you `TryCast` dynamically? Because at this point I don't know if it's a TextBox. I tried `Dim t As Type = TypeOf(obj)` and entered the type in the `TryCast` but didn't work for some reason. – Dyrdek Oct 14 '15 at 12:41
  • My fault I should have used `GetType` instead of `TypeOf` I think. Next try. – Dyrdek Oct 14 '15 at 12:46
1

What you want is something along these lines:

If obj.GetType() Is GetType(TextBox) then
   AddHandler obj.Leave, Address myNewRoutine
End If

Note that you can't just have is TextBox you need to use GetType again.

Dom Sinclair
  • 2,458
  • 1
  • 30
  • 47
  • class `object` does not have an event `Leave` - you need to cast first to `TextBox` but apparently this is also causing an issue. – Ric Oct 14 '15 at 12:36
  • good catch @Ric I should have added the cast after having established that it was an object of type TextBox in order for it to know about the leave event. If this approach isn't working though I don't know what else we can do to help without seeing what is actually causing the problem. – Dom Sinclair Oct 14 '15 at 12:40
  • I know, its difficult to say really. – Ric Oct 14 '15 at 12:48