C# 监视控件以确定正在触发的事件?

C# 监视控件以确定正在触发的事件?,c#,winforms,events,C#,Winforms,Events,是否有一种方法可以列出特定WinForms控件的所有激发事件,而无需为每个可能的事件显式创建处理程序?例如,我可能希望查看在各种数据绑定操作期间DataGridView和BindingSource之间触发的事件序列。我认为您可以使用反射来完成此操作。这无法完成。如果使用Reflector查看许多框架类,则在触发事件时会发现一个常见模式: // fire event if (EventDelegate != null) EventDelegate(eventArgs); 因此,即使没有人订

是否有一种方法可以列出特定WinForms控件的所有激发事件,而无需为每个可能的事件显式创建处理程序?例如,我可能希望查看在各种数据绑定操作期间DataGridView和BindingSource之间触发的事件序列。

我认为您可以使用反射来完成此操作。

这无法完成。如果使用Reflector查看许多框架类,则在触发事件时会发现一个常见模式:

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

因此,即使没有人订阅该事件,也不会触发该事件。您可以使用反射,但由于涉及到各种事件处理程序签名,因此会有点棘手。基本上,您必须为类型中的每个事件获取
EventInfo
,并在调用之前使用属性确定要创建的委托类型
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);
            }
        }
    }
}

我不明白为什么这意味着它不能完成——它只是意味着该活动需要订阅。这和在代码中显式订阅每个事件之间有很大的区别。我认为你在吹毛求疵。通过创建硬编码委托或使用反射,您仍然在“显式”添加事件处理程序。我的回答是,他根本不想订阅这些活动(即使是通过反思),而是想以其他方式查看活动的顺序。这正是我想要的!看来我需要认真地阅读和修改反思。谢谢确实很有帮助。非常感谢。