3

コントロールを 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

ここに画像の説明を入力してください

ボタンを処理するとき (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());
}
4

1 に答える 1

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。または、取得できるイベントは 2 つだけです。

于 2014-12-11T00:15:04.740 に答える