【问题标题】:How to access control's event?如何访问控制的事件?
【发布时间】:2013-03-15 19:51:47
【问题描述】:

我正在尝试获取分配给控制的事件的名称 例如:我有两个表单 ABForm B 包含 GridControl 并且 gridcontrol 有一些事件,例如 gridControl1_Validating。

我的目标只是知道分配给控件的事件是什么

我的代码如下 甲型

 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);

     }

在编译时我得到了控制,但我在 eventinfo 处得到了空值 虽然gridcontrol事件在form B

中有这个事件

请帮忙

【问题讨论】:

标签: c# winforms delegates event-handling controls


【解决方案1】:

尝试"Validating" 而不是"gridControl1.Validating""

var eventinfo = FoundControls[0].GetType().GetEvent(
    "Validating",
    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

尽管这与您已将事件处理程序附加到事件这一事实无关。您正在获取事件本身,而不是附加的处理程序。你不能对eventInfo 变量做任何有用的事情(除了添加和删除其他事件处理程序)。

要访问附加的处理程序(底层委托),您需要查看事件实现的代码(使用反编译器,如 ReflectordotPeek,或使用 Microsoft Reference Source):

public event CancelEventHandler Validating
{
    add
    {
        base.Events.AddHandler(EventValidating, value);
    }
    remove
    {
        base.Events.RemoveHandler(EventValidating, value);
    }
}

事实证明,Control 类使用 EventHandlerList 类型的名为 Events 的属性来存储基于 key 的所有委托(在本例中为 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;
}

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;
}

最后一个方法将提取所有附加到控件事件的事件处理程序。这包括来自所有类的处理程序(甚至由 winforms 内部附加)。您还可以通过处理程序的目标对象过滤列表:

public static List<Delegate> RetrieveAllAttachedEventHandlersInObject(Control c, object handlerContainerObject)
{
    return RetrieveAllAttachedEventHandlers(c).Where(d => d.Target == handlerContainerObject).ToList();
}

现在你可以获得gridControl1formB中定义的所有事件处理函数:

RetrieveAllAttachedEventHandlersInObject(gridControl1, formB);

【讨论】:

  • 这是我的解决方案。但我的问题是我能知道与网格相关的所有其他事件是什么吗?
  • 您想要“所有附加事件处理程序的事件列表”还是“所有附加事件处理程序的列表”?
  • 是的,所有分配给网格的事件...我尝试通过 var eventinfo = FoundControls[0].GetType().GetEvents();但它给出了所有列出的事件
  • 仍然含糊不清。我用两个不同的句子陈述了两个不同的列表。你要我的第一句话还是第二句话?请选择一个! :)
  • 对于所有这些混乱我很抱歉..但我想要第二个
猜你喜欢
  • 2014-07-02
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多