簡體   English   中英

通過反射將額外的參數傳遞給事件

[英]Pass extra parameter to event with reflection

我正在使用反射將事件從Web控件綁定到我自己的方法。 這是一個通用函數,因此我事先不知道控件或事件的類型,但是事件是例如單擊(按鈕)或selectedIndexChanged(下拉列表)。 我的函數如下所示:

protected void BindEvents(WebControl ctrl, string methodName, string eventType)
{
    System.Reflection.EventInfo eventInfo = ctrl.GetType().GetEvent(eventType);
    Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, methodName);
    eventInfo.AddEventHandler(ctrl, handler);
}

我需要通過傳入一個額外的參數來了解哪個事件觸發了MyEvent(請參見下文)。 這很重要,因為每個Web控件都可以有許多調用MyEvent的事件。

//1. Standard event signature
protected void Test_Click(object sender, EventArgs e) { } 

//2. Signature for my event
protected void MyEvent(object sender, EventArgs e, string eventName) { }

創建委托時,不允許具有不同的簽名,該代碼僅在刪除最后一個參數string eventName 我嘗試通過將eventName設置為默認參數來嘗試解決方法。 我也嘗試過子類化EventArgs,但不允許對標准簽名進行任何更改。 我可以重寫控制事件以適應我的簽名,但我認為必須有一種更簡單的方法。

使用反射時,有什么方法可以將這個額外的參數傳遞給函數?

盡管不是很漂亮,但這可以解決問題:

    protected void BindEvents(WebControl ctrl, string methodName, string eventType)
    {
        System.Reflection.EventInfo eventInfo = ctrl.GetType().GetEvent(eventType);
        var delegateType = eventInfo.EventHandlerType.GetMethod("Invoke");
        var methodInfo = this.GetType().GetMethod(methodName);
        var parameters = delegateType.GetParameters();
        if (parameters.Length!=2)
            throw new NotImplementedException(); // Can make switch and multiple CreateAction methods to handle
        var genericCreateAction = this.GetType().GetMethod("CreateAction2");
        var parameterTypes = parameters.Select(o => o.ParameterType).ToArray<Type>();
        var createAction = genericCreateAction.MakeGenericMethod(parameterTypes);
        var action = (Delegate)createAction.Invoke(this, new object[] { methodInfo, eventType });
        var properTypeAction = Delegate.CreateDelegate(eventInfo.EventHandlerType, action.Target, action.Method);
        eventInfo.AddEventHandler(ctrl, properTypeAction);
    }

    public Action<T1, T2> CreateAction2<T1, T2>(MethodInfo methodInfo, string eventName)
    {
        return (Action<T1, T2>)((p1, p2) => { methodInfo.Invoke(this, new object[] { p1, p2, eventName }); });
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM