尝试获取与Control事件关联的委托时出现问题
我试图将控件序列化为XML,我想序列化他们的事件处理程序。
我正在使用这段代码:
Control childCtrl = .... if (childCtrl.GetType() == typeof(Button)) { EventInfo baseEventInfo = childCtrl.GetType().GetEvent("Click"); EventHandlerList events = typeof(Control).GetProperty("Events", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic).GetValue(childCtrl, null) as EventHandlerList; object eventField = typeof(Control).GetField("Event" + baseEventInfo.Name, BindingFlags.NonPublic | BindingFlags.Static).GetValue(childCtrl); Delegate aDel = events[eventField]; xmlSerialisedForm.WriteElementString("Click", aDel.Method.ToString()); } if (childCtrl.GetType() == typeof(CheckBox)) { EventInfo baseEventInfo = childCtrl.GetType().GetEvent("CheckedChanged"); EventHandlerList events = typeof(Control).GetProperty("Events", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic).GetValue(childCtrl, null) as EventHandlerList; //Error here: GetField returns null object eventField = typeof(Control).GetField("Event" + baseEventInfo.Name, BindingFlags.NonPublic | BindingFlags.Static).GetValue(childCtrl); Delegate aDel = events[eventField]; xmlSerialisedForm.WriteElementString("CheckedChanged", aDel.Method.ToString()); }
现在我知道复选框有一个绑定事件CheckedChanged
的处理程序; 使用调试器时,我可以在EventHandlerList
看到该方法:
现在,当处理Button时,相同的代码实际上有效(当我想让委托与Click
事件相关联时)。 为什么它不适用于CheckBox? 我在这里想念的是什么?
编辑:我当前的解决方法(非常难看),我从typeof(CheckBox)
调用GetFields
并查看数组推断:
if (childCtrl.GetType() == typeof(CheckBox)) { EventHandlerList events = typeof(Control).GetProperty("Events", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic).GetValue(childCtrl, null) as EventHandlerList; object eventField = typeof(CheckBox).GetFields(BindingFlags.NonPublic | BindingFlags.Static)[0].GetValue(childCtrl); Delegate aDel = events[eventField]; xmlSerialisedForm.WriteElementString("CheckedChanged", aDel.Method.ToString()); }
令人愤怒的是, CheckedChanged
事件似乎以与.NET框架上其他事件完全不同的方式编写。 CheckStateChanged
。 他们来了。
typeof(CheckBox).GetField("EVENT_CHECKEDCHANGED", BindingFlags.NonPublic | BindingFlags.Static| BindingFlags.Instance | BindingFlags.FlattenHierarchy); typeof(CheckBox).GetField("EVENT_CHECKSTATECHANGED", BindingFlags.NonPublic | BindingFlags.Static| BindingFlags.Instance | BindingFlags.FlattenHierarchy);
只是为了让它变得更加特别,你不能把所有东西当作CheckBox
来对待,或者那些是你将获得的唯一两件事。