CodeGo.net>如何检查分配了哪个事件?

我的代码如下.

Control[] FoundControls = null;
FoundControls = MyFunctionToFilter(TF, c => c.Name != null && c.Name.StartsWith("grid"));
var eventinfo = FoundControls[0].GetType().GetEvents();

但是,eventinfo给我列出了属于网格的所有控件的列表.
而在主类中仅定义了两个事件,即KeyDown和Validating.

如何获得这些分配的事件的列表,即Keydown和Validating?

解决方法:

Windows Forms(WinForms)具有一个复杂的组件事件模型(而DataGridView是一个组件).有些事件是从Control继承的(例如FontChanged,ForeColorChanged等),但是所有特定于组件事件的事件都存储在单个EventHandlerList对象中,该对象是从Component继承的(顺便说一句,Control的事件也存储在此处,请参见更新)答案的结尾).有一个受保护的事件属性,用于:

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.您可以使用与上述相同的方法来获取这些密钥并检查是否附加了处理程序.

上一篇:以C#形式实施标尺


下一篇:我可以将方法分配给多个基于表单的事件吗?