0

For example, with winform, I drag a button named button1 on the winform.

this.button1.Click += new System.EventHandler(this.button1_Click);
this.button1.Click += new System.EventHandler(this.Alert);

the answer is how can I get the function names bound to button1 in code.

I want to get the function names,then use names to find source codes about button1, when user click button1, I will give the source code about button1.

PiotrWolkowski
  • 8,408
  • 6
  • 48
  • 68
SupperLee
  • 15
  • 5
  • 1
    its not an exact dup of [Has an event handler already been added?](http://stackoverflow.com/questions/136975/has-an-event-handler-already-been-added) - but that has the answers - google is your friend – BugFinder Apr 26 '16 at 12:38

2 Answers2

2

You will have to use reflection and GetInvocationList method. Below a sample that retrieves names of a handlers for a button.Click and puts them in a list:

    public Form1()
    {
        InitializeComponent();

        this.button1.Click += Button1_Click;
        this.button1.Click += Button1_Click1;

        PropertyInfo propertyInfo = button1.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
        EventHandlerList eventHandlerList = propertyInfo.GetValue(button1, new object[] { }) as EventHandlerList;
        FieldInfo fieldInfo = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static);

        var eventKey = fieldInfo.GetValue(button1);
        var eventHandler = eventHandlerList[eventKey] as Delegate;
        Delegate[] invocationList = eventHandler.GetInvocationList();

        var names = new List<string>();

        foreach (var handler in invocationList)
        {
            names.Add(handler.GetMethodInfo().Name);
        }
    }

This approach can be easily applied to other events as well. You will have to replace "EventClick" to whatever event you want to test:

FieldInfo fieldInfo = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static);
PiotrWolkowski
  • 8,408
  • 6
  • 48
  • 68
  • The question was tagged as winforms. I'm not sure, but I think you are referring to wpf. Can't find the fields you mentioned in `System.Windows.Forms.Button` class. Anyway, nice solution. – René Vogt Apr 26 '16 at 13:33
  • @RenéVogt No, that's definitely winforms solution. Tested in winforms enfironment. – PiotrWolkowski Apr 26 '16 at 14:00
  • Ok. Upvoted, because you don't need an own inherited class like in my solution. – René Vogt Apr 26 '16 at 14:04
  • Thank you your answer. I have many controls like button1,and each control may have not only one function bind to event,and the event may not be Click.So I need think about many problities and write codes for every control?need your deep answers,Thank you again~ – SupperLee Apr 26 '16 at 14:10
0

That's not so easy. Events declared in a class only expose add and remove to users of that class. You can access the invocation list of the event only from inside the class.

So one way you may achieve this is to inherit your own MyButton class like this:

public class MyButton : Button
{
    private event EventHandler MyClick;
    public new event EventHandler Click
    {
        add
        {
            MyClick += value;
            base.Click += value;
        }
        remove
        {
            MyClick -= value;
            base.Click -= value;
        }
    }
    public Delegate[] GetClickHandlers()
    {
        return MyClick?.GetInvocationList();
    }
}

So I create a new Click event that wraps the base.Click event and stores the invocation list in an extra event.

You can than get the names of the associated handlers like this:

Console.WriteLine(
    string.Join(Environment.NewLine, 
        button1.GetClickHandlers().Select(h => h.Method.Name)));

But now that I see this code, you could probably store/remove the values passed to add and remove in a separate list instead of using MyClick, but the idea is the same.

Your main problem is that you cannot call GetInvocationList() on Button.Click.

René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • so sorry,this can't solve my problem.Because I have too many controls like button1,I can't rewrite each of them.Thank you all the same ~ – SupperLee Apr 26 '16 at 14:38