mercredi 18 juillet 2018

VB.NET Add Any EventHandler Class with Delegate

I've found a few posts (not many) that I thought might solve my problem but in all my reading I still don't have a solution.

What I'm trying to do is basically create a method that will bind any given control's event to any given object's method using Reflection.EventInfo and Reflection.MethodInfo. I'm using Winforms, I'd love to just use WPF but that's not an option unfortunately.

I have an abstract BoundControl class that is just an empty canvas for inherited controls. In that class is the function below:

Public Sub CallMethod(eventName As String, sender As Object, e As EventArgs)
...
End Sub

This is what I want to be called whenever a given control's event is raised. The logic in that method calls the correct method on the data context (I've set this up to mimic WPF). This is working fine, my problem is actually binding the above method to a control's event.

I bind using the method below (in the same class as the method above). Note that I've removed the unimportant logic, stuff like my custom binding tag class and anything else unrelated to my problem:

Public Sub SetEventBind(ByRef ctrl as Control)
    Dim ctrlStr As String = "EventName"
    Dim ctrlEvent as Reflection.EventInfo = ctrl.GetType.GetEvent(ctrlStr)
    Dim eh As EventHandler = (Sub(sender, e) CallMethod(ctrlStr, sender, e))
    ctrlEvent.AddEventHandler(ctrl, eh)
End Sub

I'm trying to run my code on a LinkLabel for the LinkClicked event but I want this to work for any control's events. What ends up happening is EventHandler type cannot be converted to LinkLabelLinkClickedEventHandler. So just to test I tried the code below and it DID work:

Public Sub SetEventBind(ByRef ctrl as Control)
    Dim ctrlStr As String = "EventName"
    Dim ctrlEvent as Reflection.EventInfo = ctrl.GetType.GetEvent(ctrlStr)
    Dim eh As LinkLabelLinkClickedEventHandler = (Sub(sender, e) CallMethod(ctrlStr, sender, e))
    ctrlEvent.AddEventHandler(ctrl, eh)
End Sub

But the problem is LinkLabelLinkClickedEventHandler won't work for, say, a button click or a checkbox checked change. I also tried the code below and it didn't work:

Public Sub SetEventBind(ByRef ctrl as Control)
    Dim ctrlStr As String = "EventName"
    Dim ctrlEvent as Reflection.EventInfo = ctrl.GetType.GetEvent(ctrlStr)
    Dim eh As [Delegate] = [Delegate].CreateDelegate(ctrlevent.EventHandlerType, Me, (Sub(sender, e) CallMethod(ctrlStr, sender, e)).Method)
    ctrlEvent.AddEventHandler(ctrl, eh)
End Sub

I guess my question is multi-part. I think if I could dynamically create a delegate of the same type as ctrlEvent.EventHandlerType then I could get this working. Is it possible to dynamically set variable's type? If not, is there another way to dynamically bind any control's event to a method?





Aucun commentaire:

Enregistrer un commentaire