Наблюдайте за управлением, чтобы определить, какие события запускаются? - PullRequest
8 голосов
/ 31 марта 2009

Есть ли способ перечислить все запущенные события для определенных элементов управления WinForms без явного создания обработчика для каждого возможного события? Например, мне может понадобиться увидеть последовательность событий, которые возникают между DataGridView и BindingSource во время различных действий привязки данных.

Ответы [ 3 ]

8 голосов
/ 31 марта 2009

Вы можете использовать рефлексию, но она будет немного хитрой из-за различных сигнатур обработчиков событий. По сути, вам нужно получить EventInfo для каждого события в типе и использовать свойство EventHandlerType, чтобы определить тип создаваемого делегата перед вызовом AddEventHandler , Delegate.CreateDelegate работает для всего, что следует обычному шаблону обработчика событий, хотя ...

Вот пример приложения. Обратите внимание, что он не выполняет никакой проверки - если вы дадите ему что-то с «нестандартным» событием, оно выдаст исключение. Вы также можете довольно легко использовать отражение, чтобы распечатать аргументы событий.

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);
            }
        }
    }
}
1 голос
/ 31 марта 2009

Я думаю, вы могли бы использовать Reflection для этого.

0 голосов
/ 31 марта 2009

Это не может быть сделано. Если вы используете Reflector для просмотра большого количества классов Framework, вы найдете общий шаблон при запуске событий:

// fire event
if (EventDelegate != null)
   EventDelegate(eventArgs);

То есть событие даже не запускается, если на него никто не подписывается

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...