我有一个关于 C# 中的事件和反射的问题。我目前正在使用 Microsoft Kinect (SDK 1.7) 进行编程,并希望实现与“Push-To-Press”方法不同的点击。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 并调用正确方法的控件是从 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 始终保持不变,如果试图访问它null
会导致异常。eventDelegate
不幸的是,我无法找到在这种情况下找不到 ClickEvent 的原因。该成员eventName
的值“Click”是 KinectControl 类中事件的名称。我还在这个网站上搜索了答案(但到目前为止,没有一个解决方案对我有帮助),我阅读了各种有关 DotNetPearls.com 之类的博客,但我似乎仍然无法在这里找到错误。我希望你能帮助我。提前致谢!
编辑:添加BindingFlags.Static
;在 FieldInfo 中忘记了这一点。谢谢@Michael Gunter。不过还是不行。