问题在试图让关联到一个控件的事件委托 [英] Issue when trying to get the delegate associated to a Control's event

查看:136
本文介绍了问题在试图让关联到一个控件的事件委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图序列化到XML的控制,我想序列化的事件处理程序



我使用这段代码:

 控制childCtrl = .... 

如果(childCtrl.GetType()== typeof运算(按钮)){
EventInfo baseEventInfo = childCtrl.GetType()GetEvent(点击);

EventHandlerList事件=
typeof运算(控制).GetProperty(事件,
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.Static |
BindingFlags.NonPublic可).GetValue(childCtrl,NULL)
作为EventHandlerList;
对象eventField = typeof运算(控制).GetField(事件+ baseEventInfo.Name,
BindingFlags.NonPublic可|
BindingFlags.Static).GetValue(childCtrl);
代表阿德尔=事件[eventField]

xmlSerialisedForm.WriteElementString(点击,aDel.Method.ToString());
}

如果(childCtrl.GetType()== typeof运算(复选框)){
EventInfo baseEventInfo = childCtrl.GetType()GetEvent(的CheckedChanged);

EventHandlerList事件=
typeof运算(控制).GetProperty(事件,
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.Static |
BindingFlags.NonPublic可).GetValue(childCtrl,NULL)
作为EventHandlerList;
//错误的位置:getfield命令返回null
对象eventField = typeof运算(控制).GetField(事件+ baseEventInfo.Name,
BindingFlags.NonPublic可|
BindingFlags.Static) .GetValue(childCtrl);
代表阿德尔=事件[eventField]
xmlSerialisedForm.WriteElementString(的CheckedChanged,aDel.Method.ToString());
}

现在我的知道的该复选框,有一个处理程序开往事件的CheckedChanged ;使用调试器的时候,我可以看到在 EventHandlerList 这个方法:





现在相同的代码与按钮打交道时的实际工作(当我想获得相关的委托点击事件)。为什么不工作的复选框?什么?我在这里缺少



编辑:我目前的解决方法(很丑陋的),我从调用推断 GetFields typeof运算(复选框)和数组中寻找:

 如果(childCtrl .GetType()== typeof运算(复选框)){
EventHandlerList事件=
typeof运算(控制).GetProperty(事件,
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.Static |
BindingFlags.NonPublic可).GetValue(childCtrl,NULL)
作为EventHandlerList;

对象eventField =
的typeof(复选框).GetFields(BindingFlags.NonPublic可|
BindingFlags.Static)[0] .GetValue(childCtrl);
代表阿德尔=事件[eventField]
xmlSerialisedForm.WriteElementString(的CheckedChanged,aDel.Method.ToString());
}


解决方案

而僵硬的的CheckedChanged 事件似乎已经在一个完全不同的方式被写入在.NET Framework事件的其余部分。所以,是 CheckStateChanged 。 。在这里,他们是

  typeof运算(复选框).GetField(EVENT_CHECKEDCHANGED,
BindingFlags.NonPublic可|
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.FlattenHierarchy);
的typeof(复选框).GetField(EVENT_CHECKSTATECHANGED,
BindingFlags.NonPublic可|
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.FlattenHierarchy);



只是为了使它更加与众不同,你不能把一切都为一个复选框或这些是仅有的两个事件,你会得到。


I am trying to serialize controls to XML and I want to serialize their events' handler.

I am using this bit of code:

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());
}

Now I know that the checkbox has a handler bound for the event CheckedChanged; when using the debugger I can see that method in the EventHandlerList:

Now the same code actually works when dealing with a Button (when I want to get the delegate associated to the Click event). Why is it not working for the CheckBox? What am I missing here?

EDIT: my current workaround (very ugly) that I deduced from calling GetFields on typeof(CheckBox) and looking in the array:

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());
}

解决方案

Rather infuriatingly, the CheckedChanged event seems to have been written in an entirely different fashion to the rest of the Events on the .NET framework. So was CheckStateChanged. Here they are.

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);

Just to make it more special, you can't treat everything as a CheckBox or those are the only two events you will get.

这篇关于问题在试图让关联到一个控件的事件委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆