Windows Forms (WinForms) 拥有一个针对组件(包括 DataGridView
)的事件模型。一些事件从 Control
继承而来(例如 FontChanged
,ForeColorChanged
等),但是所有特定于组件的事件都存储在单个 EventHandlerList 对象中,该对象继承自 Component
(顺便说一下,控件事件也存储在那里,参见答案末尾的更新)。这里有一个受保护的 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); }
}
如您所见,将委托(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
。您可以使用上述相同的方法获取这些键,并检查是否附加了处理程序。