Windowsフォーム(WinForms)には、コンポーネントのイベントのトリッキーなモデルがあります(DataGridView
これはコンポーネントです)。一部のイベントControl
(FontChanged
、ForeColorChanged
など)はから継承されますが、コンポーネントイベントに固有のすべては、から継承される単一のEventHandlerListオブジェクトに格納されますComponent
(ところで、Controlからのイベントもそこに格納されます。最後の更新を参照してください)。答え)。そのための保護されたEvents
プロパティがあります:
protected EventHandlerList Events
{
get
{
if (this.events == null)
this.events = new EventHandlerList(this);
return this.events;
}
}
そして、イベントハンドラーをイベントに追加する方法は次のDataGridView
とおりです。
public event DataGridViewCellEventHandler CellValueChanged
{
add { Events.AddHandler(EVENT_DATAGRIDVIEWCELLVALUECHANGED, value); }
remove { Events.RemoveHandler(EVENT_DATAGRIDVIEWCELLVALUECHANGED, value); }
}
ご覧のとおり、デリゲート(値)はEventHandlerList
いくつかのキー値とともに渡されます。すべてのイベントハンドラーは、キーによってそこに格納されます。EventHandlerList
オブジェクトをキーとして、デリゲートを値として持つ辞書と考えることができます。したがって、リフレクションを使用してコンポーネントのイベントを取得する方法は次のとおりです。最初のステップは、これらのキーを取得することです。すでにお気づきのように、それらは次のように名前が付けられていEVENT_XXX
ます:
private static readonly object EVENT_DATAGRIDVIEWCELLVALUECHANGED;
private static readonly object EVENT_DATAGRIDVIEWCELLMOUSEUP;
// etc.
だからここに行きます:
var keys = typeof(DataGridView) // You can use `GetType()` of component object.
.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy)
.Where(f => f.Name.StartsWith("EVENT_"));
次に、私たちが必要ですEventHandlerList
:
var events = typeof(DataGridView) // or GetType()
.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
// Could be null, check that
EventHandlerList handlers = events.GetValue(grid) as EventHandlerList;
そして最後のステップは、ハンドラーがアタッチされているキーのリストを取得することです。
var result = keys.Where(f => handlers[f.GetValue(null)] != null)
.ToList();
それはあなたに鍵を与えるでしょう。デリゲートが必要な場合は、ハンドラーリストでデリゲートを探してください。
更新:から継承されたイベントControl
もに格納されEventHandlerList
ますが、何らかの理由で、キーの名前が。のように異なりますEventForeColor
。上記と同じアプローチを使用して、これらのキーを取得し、ハンドラーが接続されているかどうかを確認できます。