我正在尝试获取分配给控件的事件的名称 例如:我有两种形式 A 和 B 。表格B 包含 GridControl ,而gridcontrol有一些事件,如 gridControl1_Validating
我的目标只是知道分配给控件的事件是什么
我的守则如下 FOrm A
public Control[] FilterControls(Control start, Func<Control, bool> isMatch)
{
var matches = new List<Control>();
Action<Control> filter = null;
(filter = new Action<Control>(c =>
{
if (isMatch(c))
matches.Add(c);
foreach (Control c2 in c.Controls)
filter(c2);
}))(start);
return matches.ToArray();
}
static void main[]
{
Control[] FoundControls = null;
FoundControls = FilterControls(TF, c => c.Name != null && c.Name.StartsWith("grid"));
var eventinfo = FoundControls[0].GetType().GetEvent("gridControl1.Validating", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
}
ON编译我得到了我的控制权但是我在 eventinfo 时变为空 虽然gridcontrol事件在表单B
中有此事件请帮忙
答案 0 :(得分:0)
尝试"Validating"
代替"gridControl1.Validating"
“
var eventinfo = FoundControls[0].GetType().GetEvent(
"Validating",
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
虽然这与您已将事件处理程序附加到事件的事实无关。您正在获取事件本身,而不是附加的处理程序。您无法对eventInfo
变量执行任何有用的操作(除了添加和删除其他事件处理程序之外)。
要访问附加的处理程序(底层委托),您需要查看事件实现的代码(使用反编译器,如Reflector或dotPeek,或使用Microsoft Reference Source):
public event CancelEventHandler Validating
{
add
{
base.Events.AddHandler(EventValidating, value);
}
remove
{
base.Events.RemoveHandler(EventValidating, value);
}
}
事实证明,Control
类使用类型为EventHandlerList
的名为Events
的属性来存储基于键的所有委托({{1在这种情况下,字段)。
要检索事件的委托,我们应该从EventValidating
属性中读取它们:
Events
和
public static Delegate[] RetrieveControlEventHandlers(Control c, string eventName)
{
Type type = c.GetType();
FieldInfo eventKeyField = GetStaticNonPublicFieldInfo(type, "Event" + eventName);
if (eventKeyField == null)
{
eventKeyField = GetStaticNonPublicFieldInfo(type, "EVENT_" + eventName.ToUpper());
if (eventKeyField == null)
{
// Not all events in the WinForms controls use this pattern.
// Other methods can be used to search for the event handlers if required.
return null;
}
}
object eventKey = eventKeyField.GetValue(c);
PropertyInfo pi = type.GetProperty("Events",
BindingFlags.NonPublic | BindingFlags.Instance);
EventHandlerList list = (EventHandlerList)pi.GetValue(c, null);
Delegate del = list[eventKey];
if (del == null)
return null;
return del.GetInvocationList();
}
// Also searches up the inheritance hierarchy
private static FieldInfo GetStaticNonPublicFieldInfo(Type type, string name)
{
FieldInfo fi;
do
{
fi = type.GetField(name, BindingFlags.Static | BindingFlags.NonPublic);
type = type.BaseType;
} while (fi == null && type != null);
return fi;
}
最后一个方法将提取附加到控件事件的所有事件处理程序。这包括来自所有类的处理程序(甚至由winforms内部附加)。您还可以通过处理程序的目标对象筛选列表:
public static List<Delegate> RetrieveAllAttachedEventHandlers(Control c)
{
List<Delegate> result = new List<Delegate>();
foreach (EventInfo ei in c.GetType().GetEvents())
{
var handlers = RetrieveControlEventHandlers(c, ei.Name);
if (handlers != null) // Does it have any attached handler?
result.AddRange(handlers);
}
return result;
}
现在,您可以获取public static List<Delegate> RetrieveAllAttachedEventHandlersInObject(Control c, object handlerContainerObject)
{
return RetrieveAllAttachedEventHandlers(c).Where(d => d.Target == handlerContainerObject).ToList();
}
中定义的gridControl1
的所有事件处理程序:
formB