[英]finding events via reflection c#
我有一个关于C#中的事件和反射的问题。 我目前正在使用Microsoft Kinect(SDK 1.7)进行编程,并希望实现与“按按”方法不同的单击。 ClickEvent本身在KinectControl类中声明。
public partial class KinectControl : UserControl
{
/**
\brief Default Click event
*/
public static readonly RoutedEvent ClickEvent =
EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(KinectControl));
[...]
public event RoutedEventHandler Click
{
add
{
AddHandler(ClickEvent, value);
}
remove
{
RemoveHandler(ClickEvent, value);
}
}
}
应该引发此ClickEvent并调用适当方法的Control是从KinectControl类继承的“ Menu_Point”对象。
识别点击手势后,“源”或“ Menu_Point”对象分别引发ClickEvent,如下所示:
invokeCtrl.Raise<RoutedEventArgs>("Click", new RoutedEventArgs(KinectControl.ClickEvent));
调用以下方法:
public static void Raise<TEventArgs>(this object source, string eventName, TEventArgs eventArgs) where TEventArgs : EventArgs
{
var list =
source.GetType().GetFields(BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance |
BindingFlags.Static | BindingFlags.SetField |
BindingFlags.InvokeMethod | BindingFlags.Instance);
FieldInfo fieldInfo =
source.GetType().GetField(eventName, BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static |
BindingFlags.GetField);
var eventDelegate =
(MulticastDelegate)fieldInfo.GetValue(source);
if (eventDelegate != null)
{
foreach (var handler in eventDelegate.GetInvocationList())
{
handler.Method.Invoke(handler.Target, new object[]{ source, eventArgs });
}
}
}
在调用Raise方法并到达此行之前,它工作正常: FieldInfo fieldInfo = source.GetType().GetField(eventName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.GetField);
我不知道为什么,但是fieldInfo ist始终保持为null
,如果eventDelegate
试图获取对它的访问权限,则会导致异常。 不幸的是,在这种情况下,我无法找到未找到ClickEvent的原因。 成员eventName
的值“ Click”是KinectControl类中Event的名称。 我也在该站点上搜索了答案(但是到目前为止,没有一种解决方案对我有帮助),并且我阅读了各种有关DotNetPearls.com之类的博客,但我似乎仍然找不到这里的错误。 我希望你能帮助我。 提前致谢!
编辑:添加BindingFlags.Static
; 在FieldInfo中忘记了。 谢谢@迈克尔·甘特。 不过仍然无法正常工作。
这似乎可行:
var eventField = source.GetType().GetField(eventName, BindingFlags.Instance | BindingFlags.NonPublic);
var eventDelegate = eventField.GetValue(source) as MulticastDelegate;
if (eventDelegate != null)
eventDelegate.DynamicInvoke(new object[] { source, eventArgs });
如果只调用UIElement.RaiseEvent
会更好-RoutedEvents不需要实际的EventHandler实现-这就是为什么它们仅将工作委托给UIElement.AddHandler
和UIElement.RemoveHandler
。
话虽如此-这是您最有可能找到活动的方式:
public static RoutedEvent GetEvent(this UIElement source, string eventName)
{
if (source == null)
throw new ArgumentNullException("source");
if (string.IsNullOrEmpty(eventName))
throw new ArgumentException("eventName");
// check if the type is directly in there, otherwise you need a second pass and a more general approach
RoutedEvent routedEvent = null;
// this may return null...
RoutedEvent[] events = EventManager.GetRoutedEventsForOwner(source.GetType());
if (events != null)
routedEvent = events.FirstOrDefault(p => p.Name == eventName);
return routedEvent ?? EventManager.GetRoutedEvents().FirstOrDefault(p => p.OwnerType.IsInstanceOfType(source) && p.Name == eventName);
}
public static void RaiseEvent(this UIElement source, string eventName)
{
RoutedEvent routedEvent = GetEvent(source, eventName);
if (routedEvent != null)
source.RaiseEvent(new RoutedEventArgs(routedEvent, source));
}
}
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.