1

I am trying to determine the method that Click event is subscribed to, in my form, and I follow the guide here.

Whereas the forum post above able to get the list that the Click event is subscribing to by following code

 hasClickEventHandler = HasEventHandler(buttonControl, "EventClick");
    Assert.AreEqual(hasClickEventHandler, true);


    private bool HasEventHandler(Control control, string eventName)
    {
        EventHandlerList events =
            (EventHandlerList)
            typeof(Component)
             .GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance)
             .GetValue(control, null);

        object key = typeof(Control)
            .GetField(eventName, BindingFlags.NonPublic | BindingFlags.Static)
            .GetValue(null);

        Delegate handlers = events[key];

        return handlers != null && handlers.GetInvocationList().Any();
    }

I can't.

I then use var keys = typeof(Control).GetFields(BindingFlags.NonPublic | BindingFlags.Static); to check, and I found that one of the Keys does seem to have the correct event name. ie,

keys[19].FullName=="System.Windows.Forms.Control.EventClick";
keys[19].Name=="EventClick";

So there is no reason why

object key = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static)

And

object key = typeof(Control).GetField("System.Windows.Forms.Control.EventClick", BindingFlags.NonPublic | BindingFlags.Static)

Returns null, and yet this is exactly what happen

Why is this so? What could have gone wrong?

Here's my exact code

        var form = new Form1();
        EventHandlerList events = (EventHandlerList)typeof(Control)
            .GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance)
            .GetValue(form, null);
        var keys = typeof(Control).GetFields(BindingFlags.NonPublic | BindingFlags.Static);
        var name = keys[19].Name;  //name="EventClick"
       object key = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static);  //null

Edit: I can reproduce the behavior on .Net 4.5.2, however, on .Net 4.6, key is a valid object. This seems to be a specific bug in .Net 4.5.2

Graviton
  • 81,782
  • 146
  • 424
  • 602
  • hmmm... looks like it should work, indeed – Marc Gravell May 01 '17 at 10:54
  • @MarcGravell, it's just very puzzling, I've appended my full code – Graviton May 01 '17 at 11:01
  • If you find EventClick back at index [19] then you have a very unusual .NET version. I'd have to guess at .NET 4.7, blissfully not installed on any of my machines yet, there is a fair amount of tinkering with Winforms in that release. Otherwise the hazard of code like this. Use a decent decompiler to dig around a bit. – Hans Passant May 01 '17 at 11:55
  • @HansPassant , what is the usual location of event click on your side? – Graviton May 01 '17 at 13:18
  • It is [17] on both 3.5 and 4.6.2. It ought to be easier if you just tell us what you use. – Hans Passant May 01 '17 at 13:23
  • @HansPassant, this appears to be a bug on .Net 4.5.2. When I target my application at 4.6, `key` is now a valid object. – Graviton May 01 '17 at 14:00

1 Answers1

1

My solution: Changing the target from .Net 4.5.2 to .Net 4.6 fixes the issue; in .Net 4.6

 object key = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static);

key gives a valid object

Graviton
  • 81,782
  • 146
  • 424
  • 602