.net 从控件跟踪(所有)事件

.net 从控件跟踪(所有)事件,.net,visual-studio,debugging,events,controls,.net,Visual Studio,Debugging,Events,Controls,简单情况(VS2005,.NET2):我在面板1上有一个textBox1。我需要跟踪此文本框1中发出的所有事件。 实际上,当我需要从这个textBox1跟踪单个事件(例如TextChanged)时,我会向(TextChanged事件)添加一个处理程序,然后设置一个非阻塞breackpoint,在输出控制台上写入一条包含函数(eventhandler)名称的消息。 因此,对于单个事件,我可以编写这个处理程序并设置breackpoint,但是对于所有可能的textbox(或其他控件)的事件,我可以做

简单情况(VS2005,.NET2):
我在面板1上有一个textBox1。我需要跟踪此文本框1中发出的所有事件。

实际上,当我需要从这个textBox1跟踪单个事件(例如TextChanged)时,我会向(TextChanged事件)添加一个处理程序,然后设置一个非阻塞breackpoint,在输出控制台上写入一条包含函数(eventhandler)名称的消息。 因此,对于单个事件,我可以编写这个处理程序并设置breackpoint,但是对于所有可能的textbox(或其他控件)的事件,我可以做类似的事情吗

更深入地说,我需要知道在所提到的控件(文本框)的特定时刻发生了什么事件


谢谢。

您不能自动执行此操作


但是,如果您只是想知道什么时候触发了哪些事件,请尝试Spy++。

您无法自动执行此操作


但是,如果您只是想知道什么时候触发了哪些事件,请尝试Spy++。

您可以使用反射获取对象的所有事件,并将它们全部挂接到您的调试方法中

void HookAllEvents(object obj)
{
    foreach (var evInfo in obj.GetType().GetEvents())
    {
        evInfo.AddEventHandler(obj, new EventHandler(DebugEventHandler));
    }
}

void DebugEventHandler(object sender, EventArgs e)
{
}

不要忘了在结尾处解开钩子:)

您可以使用反射来获取对象的所有事件,并将它们全部挂接到您的调试方法中

void HookAllEvents(object obj)
{
    foreach (var evInfo in obj.GetType().GetEvents())
    {
        evInfo.AddEventHandler(obj, new EventHandler(DebugEventHandler));
    }
}

void DebugEventHandler(object sender, EventArgs e)
{
}

不要忘了在结尾处解开钩:)

Aviad的帖子是一个好的开始。您可以将其用于类型为
EventHandler
的事件。对于其他委托类型,您可以使用相同的技术为每种类型手动创建处理程序

如果您想更加灵活,应该在运行时使用
System.Reflection.Emit
创建事件处理程序。下面是一个详细的解释:。向下滚动至“使用动态方法在运行时生成事件处理程序”标题

//编辑

我创建了一个简单的类,它能够处理特定对象的所有事件,并将它们传递给通用事件处理程序。代码基于和中的示例

基本理念

  • 在运行时中创建与事件具有相同参数的方法
  • 将此方法设置为.GetEvents()类型中每个事件的事件处理程序
  • 从该方法调用通用事件处理程序
用法

public delegate void UniversalEventHandler(string eventName, object[] args);

public class EventInspector
{
    private UniversalEventHandler eventHandler;
    private object srcObject;

    public EventInspector(object srcObject, UniversalEventHandler eventHandler)
    {
        this.eventHandler = eventHandler;
        this.srcObject = srcObject;
        Attach();
    }

    public void EventReceived(string eventName, object[] args)
    {
        if (eventHandler != null)
            eventHandler(eventName, args);
    }

    public void Attach()
    {
        Type type = srcObject.GetType();
        EventInfo[] srcEvents = type.GetEvents();

        for (int i = 0; i < srcEvents.Length; i++)
        {
            EventInfo srcEvent = srcEvents[i];

            Type[] parameterTypes = GetDelegateParams(srcEvent.EventHandlerType);
            DynamicMethod handler = new DynamicMethod("", typeof(void), parameterTypes, typeof(EventInspector));
            string name = srcEvent.Name;
            ILGenerator il = handler.GetILGenerator();
            il.DeclareLocal(typeof(object[]));
            il.DeclareLocal(typeof(string));

            il.Emit(OpCodes.Ldstr, srcEvent.Name);
            il.Emit(OpCodes.Stloc_1);
            il.Emit(OpCodes.Ldc_I4, parameterTypes.Length - 1);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc_0);

            for (int j = 0; j < parameterTypes.Length - 1; j++)
            {
                Type parameter = parameterTypes[j];
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Ldc_I4, j);
                il.Emit(OpCodes.Ldarg, j + 1);
                il.Emit(OpCodes.Stelem_Ref);
            }

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldloc_1);
            il.Emit(OpCodes.Ldloc_0);

            MethodInfo eventReceivedMethod = this.GetType().GetMethod("EventReceived", BindingFlags.Public | BindingFlags.Instance);
            il.EmitCall(OpCodes.Callvirt, eventReceivedMethod, null);
            il.Emit(System.Reflection.Emit.OpCodes.Ret);                                 

            srcEvent.AddEventHandler(srcObject, handler.CreateDelegate(srcEvent.EventHandlerType, this));
        }
    }

    private Type[] GetDelegateParams(Type d)
    {
        MethodInfo delegateMethod = d.GetMethod("Invoke");
        ParameterInfo[] delegateParams = delegateMethod.GetParameters();

        Type[] result = new Type[delegateParams.Length + 1];
        result[0] = this.GetType();

        for (int i = 0; i < delegateParams.Length; i++)
        {
            result[i + 1] = delegateParams[i].ParameterType;
        }

        return result;
    }
}
要附加到的对象在构造函数中传递。下一个类型为
UniversalEventHandler
的匿名方法用于处理所有事件。此方法以
eventName
的形式接收事件名称,并在
args
中接收事件参数。您可以在此方法上设置断点,并在VisualStudio中检查参数或自己打印参数。在本示例中,仅打印事件名称,并且可以在输出窗口(Visual Studio中的菜单视图>输出)中找到。在此示例中,检查标准按钮
button1

private void Form1_Load(object sender, EventArgs e)
{            
    UniversalEventHandler handler = (UniversalEventHandler) delegate(string eventName, object[] args)
    {
        System.Diagnostics.Trace.WriteLine(eventName);
    };

    EventInspector inspector = new EventInspector(button1, handler);

}
代码

public delegate void UniversalEventHandler(string eventName, object[] args);

public class EventInspector
{
    private UniversalEventHandler eventHandler;
    private object srcObject;

    public EventInspector(object srcObject, UniversalEventHandler eventHandler)
    {
        this.eventHandler = eventHandler;
        this.srcObject = srcObject;
        Attach();
    }

    public void EventReceived(string eventName, object[] args)
    {
        if (eventHandler != null)
            eventHandler(eventName, args);
    }

    public void Attach()
    {
        Type type = srcObject.GetType();
        EventInfo[] srcEvents = type.GetEvents();

        for (int i = 0; i < srcEvents.Length; i++)
        {
            EventInfo srcEvent = srcEvents[i];

            Type[] parameterTypes = GetDelegateParams(srcEvent.EventHandlerType);
            DynamicMethod handler = new DynamicMethod("", typeof(void), parameterTypes, typeof(EventInspector));
            string name = srcEvent.Name;
            ILGenerator il = handler.GetILGenerator();
            il.DeclareLocal(typeof(object[]));
            il.DeclareLocal(typeof(string));

            il.Emit(OpCodes.Ldstr, srcEvent.Name);
            il.Emit(OpCodes.Stloc_1);
            il.Emit(OpCodes.Ldc_I4, parameterTypes.Length - 1);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc_0);

            for (int j = 0; j < parameterTypes.Length - 1; j++)
            {
                Type parameter = parameterTypes[j];
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Ldc_I4, j);
                il.Emit(OpCodes.Ldarg, j + 1);
                il.Emit(OpCodes.Stelem_Ref);
            }

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldloc_1);
            il.Emit(OpCodes.Ldloc_0);

            MethodInfo eventReceivedMethod = this.GetType().GetMethod("EventReceived", BindingFlags.Public | BindingFlags.Instance);
            il.EmitCall(OpCodes.Callvirt, eventReceivedMethod, null);
            il.Emit(System.Reflection.Emit.OpCodes.Ret);                                 

            srcEvent.AddEventHandler(srcObject, handler.CreateDelegate(srcEvent.EventHandlerType, this));
        }
    }

    private Type[] GetDelegateParams(Type d)
    {
        MethodInfo delegateMethod = d.GetMethod("Invoke");
        ParameterInfo[] delegateParams = delegateMethod.GetParameters();

        Type[] result = new Type[delegateParams.Length + 1];
        result[0] = this.GetType();

        for (int i = 0; i < delegateParams.Length; i++)
        {
            result[i + 1] = delegateParams[i].ParameterType;
        }

        return result;
    }
}
public委托void UniversalEventHandler(字符串eventName,object[]args);
公共类事件检查员
{
私有UniversalEventHandler事件处理程序;
私有对象;
公共事件检查器(对象srcObject、UniversalEventHandler事件处理程序)
{
this.eventHandler=eventHandler;
this.srcObject=srcObject;
附加();
}
已接收公共void EventReceived(字符串eventName,对象[]args)
{
if(eventHandler!=null)
eventHandler(eventName,args);
}
公共图书馆(附页)
{
Type Type=srcObject.GetType();
EventInfo[]srcEvents=type.GetEvents();
for(int i=0;i
Aviad的帖子是一个好的开始。您可以将其用于类型为
EventHandler
的事件。对于其他委托类型,您可以使用相同的技术为每种类型手动创建处理程序

如果您想更加灵活,应该在运行时使用
System.Reflection.Emit
创建事件处理程序。下面是一个详细的解释:。向下滚动至“使用动态方法在运行时生成事件处理程序”标题

//编辑

我创建了简单的cla