我如何可以以编程方式认购对象的所有事件? [英] How can I programmatically subscribe to all the events of an object?

查看:281
本文介绍了我如何可以以编程方式认购对象的所有事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想订阅所有按一个WPF GridView控件类第三方组件,以便做一些调试暴露事件。除了建议,这可能不是去有关调试它和类似的东西,我想知道是否可以做到这一点的最好办法。

I am trying to subscribe to ALL events exposed by a WPF GridView-like 3rd party component in order to do some debugging. Aside from the suggestion that this might not be the best way to go about debugging it and stuff like that I would like to know if this can be done.

有关的路由事件,它的工作确定是这样的:

For the routed events it worked ok like this :

var type = tree.GetType();
do
{
    var staticFields = type.GetFields(BindingFlags.Static | BindingFlags.Public);
    foreach (var staticField in staticFields)
    {
        if (typeof(RoutedEvent).IsAssignableFrom(staticField.FieldType))
        {
            tree.AddHandler((RoutedEvent)staticField.GetValue(null), new RoutedEventHandler(OnRoutedEvent), true);
        }
    }
} while ((type = type.BaseType) != typeof(object)/* && type.FullName.StartsWith("Telerik")*/);

public void OnRoutedEvent(object sender, System.Windows.RoutedEventArgs e)
{
    Debug.WriteLine(e.RoutedEvent.ToString());
}

然而,具有典型的事件这似乎并没有工作:

However, with typical events this doesn't seem to work :

var evts = tree.GetType().GetEvents();
foreach (var ev in evts)
{
    ev.AddEventHandler(this, new EventHandler(OnEvent));
}

public void OnEvent(object sender, EventArgs e)
{
      //..
}

,因为它不喜欢的任何东西,委托是事件处理程序,而不是特殊类型,或者因为事件处理方法的签名不包含特殊EventArgs类类型。

because it doesn't like either the thing that the delegate is EventHandler instead of the specialized type or because the signature of the event handler method does not contain the specialized EventArgs class type.

可以这样莫名其妙地做?

Can this be done somehow?

------------稍后编辑--------- 在这三种情况下(我的尝试,ds27680的建议和托马斯·莱维斯克的建议)中的addEventHandler调用失败:

------------ LATER EDIT --------- In all three cases (my attempt, ds27680's suggestion and Thomas Levesque's suggestion) the AddEventHandler call fails with :

        System.Reflection.TargetException occurred
            Message=Object does not match target type.
            Source=mscorlib
                StackTrace:
                   at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
                   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
                   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
                   at System.Reflection.EventInfo.AddEventHandler(Object target, Delegate handler)
                   at Test.MainWindow..ctor() in c:\users\me\documents\visual studio 2010\Projects\Test\Test\MainWindow.xaml.cs:line 39

我猜的事实,事件处理方法的签名不完全匹配的EventArgs的类型是什么使得它失败...

I guess the fact that the event handler method's signature does not match EXACTLY the EventArgs type is what makes it fail...

推荐答案

您可以尝试:

public class DebugHook
{
    public static void OnEvent<EventArgsType>(object sender, EventArgsType eventArgs)
    {

    }
}

然后:

foreach (var ev in evts)
{
   Type argsType = getEventArgsType(ev);

   MethodInfo hook = typeof(DebugHook).GetMethod("OnEvent");
   MethodInfo boundEventhandler = hook.MakeGenericMethod(new [] { argsType} );

   Delegate handler = Delegate.CreateDelegate(ev.EventHandlerType, boundEventhandler);

   ev.AddEventHandler(this, handler );
}

在这里getEventArgs看起来是这样的:

where getEventArgs looks like this:

 public Type getEventArgsType(EventInfo eventType)
 {
     Type t = eventType.EventHandlerType;
     MethodInfo m = t.GetMethod("Invoke");

     var parameters = m.GetParameters();
     return parameters[1].ParameterType;
 }

当然,有很多错误检查/处理丢失...

Of course a lot of error checking/handling is missing...

这篇关于我如何可以以编程方式认购对象的所有事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆