1

コントロールに割り当てられているイベントの名前を取得しようとしています。例: ABの 2 つのフォームがあります。フォーム 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 で null を取得していますが、gridcontrolイベントにはフォーム B でこのイベントがあります

助けてください

4

1 に答える 1

0

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

クラスはtypeControlという名前のプロパティを使用して、キー(この場合はフィールド) に基づいてすべてのデリゲートを格納することがわかります。EventsEventHandlerListEventValidating

イベントのデリゲートを取得するには、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;
}

最後のメソッドは、コントロール イベントに関連付けられたすべてのイベント ハンドラーを抽出します。これには、すべてのクラスのハンドラーが含まれます (winform によって内部的にアタッチされたものも含む)。ハンドラーのターゲット オブジェクトでリストをフィルター処理することもできます。

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

gridControl1で定義されているすべてのイベント ハンドラーを取得できますformB

RetrieveAllAttachedEventHandlersInObject(gridControl1, formB);
于 2013-03-26T05:35:33.460 に答える