如何得到组件事件的委托列表
如何得到组件事件的委托列表
{
TypecomponentType=component.GetType();
PropertyInfoeventsPropertyInfo=componentType.GetProperty("Events",BindingFlags.Instance|BindingFlags.NonPublic);
EventHandlerListeventHanlderList=eventsPropertyInfo.GetValue(component,null)asEventHandlerList;
FieldInfoHeadFieldInfo=eventHanlderList.GetType().GetField("head",BindingFlags.Instance|BindingFlags.NonPublic);
objectHeadObject=HeadFieldInfo.GetValue(eventHanlderList);
do
{
FieldInfo[]fieldInfoList=componentType.GetFields(BindingFlags.Static|BindingFlags.Instance|BindingFlags.NonPublic);
foreach(FieldInfofieldInfoinfieldInfoList)
{
objectfieldValue=fieldInfo.GetValue(component);
if(fieldValue!=null)
{
TypefieldType=fieldValue.GetType();
if(fieldType.Name==EventHandlerTypeName&&(fieldValueasDelegate)!=null)
{
return(fieldValueasDelegate).GetInvocationList();
}
elseif(fieldType.Name==typeof(Object).Name)
{
if(fieldInfo.Name.IndexOf(EventName,StringComparison.OrdinalIgnoreCase)>-1)
{
if(HeadObject!=null)
{
DelegatedelegateObject=eventHanlderList[fieldValue];
if(delegateObject!=null)
returndelegateObject.GetInvocationList();
}
}
}
}
}
componentType=componentType.BaseType;
}while(componentType!=null);
if(HeadObject!=null)
{
objectListEntry=HeadObject;
TypeListEntryType=ListEntry.GetType();
FieldInfohandlerFieldInfo=ListEntryType.GetField("handler",BindingFlags.Instance|BindingFlags.NonPublic);
FieldInfokeyFieldInfo=ListEntryType.GetField("key",BindingFlags.Instance|BindingFlags.NonPublic);
FieldInfonextFieldInfo=ListEntryType.GetField("next",BindingFlags.Instance|BindingFlags.NonPublic);
while(ListEntry!=null)
{
Delegatehandler=handlerFieldInfo.GetValue(ListEntry)asDelegate;
objectkey=keyFieldInfo.GetValue(ListEntry);
ListEntry=nextFieldInfo.GetValue(ListEntry);
if(handler!=null&&handler.GetType().Name==EventHandlerTypeName)
returnhandler.GetInvocationList();
}
}
returnnull;
}
简要说明:
1)参数说明:
component: 组件对象实例
EventName: 事件的名称,如"ItemClick"
EventHandlerTypeName: 事件委托类型,如"ItemClickEventHander"
2)代码说明:
第一段代码遍历组件的所有私有字段,尝试根据EventName和EventHandlerTypeName找出相关的字段.
如果找到了相关的字段,检查它的值是否是Delegate类型,是的话OK.如果它的值是Object类型,那么说明它是EventHandlerList的key,则需要用EventHandlerList实例[key]来得到委托列表.
第二段代码在第一段代码没找到对应的字段的情况下,检查EventHandlerList是否为空,不为空的话。遍历该组件的所有事件,尝试使用EventHandlerTypeName来找到相关的委托列表。
如果还未找到,则返回null。
3)存在的问题
可能无法找到某些组件的委托,或者找到不匹配的委托列表。
能否顺利地找到事件对应的委托列表,取决于组件内部定义的事件字段或在EventHandlerList的key字段是否与事件名称相同以及EventHandler类型是否特殊。
如果组件内部定义了与事件名称相同的字段或EventHandler类型比较特别,则较容易找到对应的委托列表。
虽然可以通过EventHandlerList来得到组件的所有事件委托,但根据得到的key却无法确定handler委托列表对应的是哪一个事件。
4)已检测过的组件和事件
没来得及仔细测试,只测试了二个XtraBar的BarButtonItem.ItemClick和XtraNavBar的NavBarItem.LinkClicked事件。