Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Watch control to determine events being fired?

Is there a way to list all fired events for specific WinForms controls without explicitly creating a handler for each possible event? For example, I might want to see the sequence of events that fire between a DataGridView and the BindingSource during various databinding actions.

like image 839
BikeMrown Avatar asked Mar 31 '09 16:03

BikeMrown


2 Answers

You could use reflection, but it's going to be slightly tricky because of the various event handler signatures involved. Basically you'd have to get the EventInfo for each event in the type, and use the EventHandlerType property to work out what delegate type to create before calling AddEventHandler. Delegate.CreateDelegate works for everything that follows the normal event handler pattern though...

Here's a sample app. Note that it's not doing any checking - if you give it something with a "non-standard" event it will throw an exception. You could fairly easily use reflection to print out the event args too.

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;

namespace ConsoleApp
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Form form = new Form { Size = new Size(400, 200) };
            Button button = new Button { Text = "Click me" };
            form.Controls.Add(button);
            EventSubscriber.SubscribeAll(button);
            Application.Run(form);
        }
    }

    class EventSubscriber
    {
        private static readonly MethodInfo HandleMethod = 
            typeof(EventSubscriber)
                .GetMethod("HandleEvent", 
                           BindingFlags.Instance | 
                           BindingFlags.NonPublic);

        private readonly EventInfo evt;

        private EventSubscriber(EventInfo evt)
        {
            this.evt = evt;
        }

        private void HandleEvent(object sender, EventArgs args)
        {
            Console.WriteLine("Event {0} fired", evt.Name);
        }

        private void Subscribe(object target)
        {
            Delegate handler = Delegate.CreateDelegate(
                evt.EventHandlerType, this, HandleMethod);
            evt.AddEventHandler(target, handler);
        }

        public static void SubscribeAll(object target)
        {
            foreach (EventInfo evt in target.GetType().GetEvents())
            {
                EventSubscriber subscriber = new EventSubscriber(evt);
                subscriber.Subscribe(target);
            }
        }
    }
}
like image 144
Jon Skeet Avatar answered Nov 05 '22 15:11

Jon Skeet


I think you could use Reflection to do this.

like image 22
John Saunders Avatar answered Nov 05 '22 16:11

John Saunders