我正在尝试将控件序列化为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?我在这里缺少什么?
编辑:我当前的解决方法(非常难看)是我在GetFields
上调用typeof(CheckBox)
并查看数组中推断出来的:
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());
}
答案 0 :(得分:2)
相当令人愤怒的是,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
,或者这是你将获得的唯一两件事。