C# 在silverlight中反射的routedevents上调用注册的EventHandler

C# 在silverlight中反射的routedevents上调用注册的EventHandler,c#,silverlight,reflection,C#,Silverlight,Reflection,我想调用FrameworkElement的所有已注册RouteEvent处理程序(例如,ContentControl/Canvas/…的MouseLeftButtonUp或MouseMove)。在我的例子中,我得到了对该对象的引用,我知道应该调用哪个事件。但是经过几个小时的思考后,我问自己这是否可能 我想做这样的事情: var eventInfo = contentControl.GetType().GetEvent("MouseLeftButtonUp", BindingFlags.Publi

我想调用FrameworkElement的所有已注册RouteEvent处理程序(例如,ContentControl/Canvas/…的MouseLeftButtonUp或MouseMove)。在我的例子中,我得到了对该对象的引用,我知道应该调用哪个事件。但是经过几个小时的思考后,我问自己这是否可能

我想做这样的事情:

var eventInfo = contentControl.GetType().GetEvent("MouseLeftButtonUp", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
var getInvocationListMethod = eventInfo.EventHandlerType.GetMethod("GetInvocationList", BindingFlags.Instance | BindingFlags.Public);
Delegate[] delegates = (Delegate[])getInvocationListMethod.Invoke(eventInfo.EventHandlerType, null);
foreach (var handler in delegates)
{
    handler.Method.Invoke(handler.Target, new object[] { contentControl, new EventArgs()});
}
这实际上总是抛出一个异常,消息为“对象与目标类型不匹配”。有人对此有线索吗

干杯
蒂姆

这比你想象的要容易得多。 要在拥有
EventInfo
对象后调用事件,只需使用
evtInfo.GetRaiseMethod(true).invoke(…)

但是代码失败的原因是,事件使用的委托需要一个
MouseButtonEventArgs
参数

因此,为了使您的示例起作用,您可以尝试以下代码:

var eventInfo = contentControl.GetType().GetEvent("MouseLeftButtonUp", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
var raise = eventInfo.GetRaiseMethod(true);
raise.Invoke(contentControl, new object[] { contentControl, new MouseButtonEventArgs(null, 0, MouseButton.Left) });
我不确定
MouseButtonEventArgs
构造函数是否允许null MouseDevice,或者您可以将参数全部保留为null:

raise.Invoke(contentControl, new object[] { contentControl, null });

很可能,这些事件是通过添加/删除访问器实现的,而不是带有委托的专用for事件字段。这就是为什么没有调用列表——它可能存储在其他地方,因为它是一个路由事件。另见。