4

デバッグを行うために、WPFGridViewのようなサードパーティコンポーネントによって公開されたすべてのイベントをサブスクライブしようとしています。これはデバッグを行うための最良の方法ではないかもしれないという提案は別として、私はこれができるかどうか知りたいと思います。

ルーティングされたイベントの場合、次のように問題なく機能しました。

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());
}

ただし、通常のイベントでは、これは機能しないようです。

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

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

デリゲートが特殊なタイプではなくEventHandlerであることが気に入らないため、またはイベントハンドラメソッドのシグネチャに特殊なEventArgsクラスタイプが含まれていないためです。

これはどういうわけか行うことができますか?

------------後の編集---------3つのケースすべて(私の試み、ds27680の提案とThomas Levesqueの提案)で、AddEventHandler呼び出しは次のように失敗します。

        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タイプが失敗する原因だと思います...

4

3 に答える 3

3

デリゲートを適切なタイプに「変換」する必要があります。

var evts = tree.GetType().GetEvents();
EventHandler tmp = OnEvent;
foreach (var ev in evts)
{
    Delegate handler = Delegate.CreateDelegate(ev.EventHandlerType, tmp.Target, tmp.Method);
    ev.AddEventHandler(this, handler);
}
于 2011-03-28T09:31:25.283 に答える
2

Delegate.CreateDelegateを使用して、特定のタイプのイベントを作成できます。試すだけの価値があります。

于 2011-03-28T09:18:20.763 に答える
2

あなたは試すことができます:

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 は次のようになります。

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

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

もちろん、多くのエラーチェック/処理が欠落しています...

于 2011-03-28T10:22:36.497 に答える