Adding Event Handlers Using Reflection

I am adding dynamic controls to the page using LoadControl and Controls.Add. I need to somehow wrap the Init and Load event handlers of these loaded controls in my code. So it should be this order of events SomeMyCode () -> Control.Init () -> AnotherMyCode () and the same for Load SomeMyCode () -> Control.Load () -> AnotherMyCode ().
My idea was to handle List List event handlers for Init and Load events and add handlers for the first and last event with the code that I have to execute. But I cannot figure out how to do this.

0


source to share


2 answers


You cannot force an event handler in front of other handlers already subscribed to the event. If you need to call method A first, you need to subscribe to A. first.


Repeat your comment which is incredibly hacked. First, you can't even rely on an event having a supporter on the delegate side; it may be one EventHandlerList

or the other that does not expose comfortable hooks without interfering with removal.



Second (and more importantly), it breaks every encapsulation rule.

In general, if you want to be first, the best approach is to override the method OnFoo()

. The second option is to subscribe first.

+1


source


Here is a draft of a working solution:



    protected void Page_Load(object sender, EventArgs e)
    {
        Control ctrl = this.LoadControl("WebUserControl1.ascx");
        PropertyInfo propertyInfo = typeof(Control).GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
        EventHandlerList eventHandlerList = propertyInfo.GetValue(ctrl, new object[]{}) as EventHandlerList;
        FieldInfo fieldInfo = typeof(Control).GetField("EventLoad", BindingFlags.NonPublic | BindingFlags.Static);

        if(fieldInfo == null)
            return;

        object eventKey = fieldInfo.GetValue(ctrl);
        Delegate eventHandler = eventHandlerList[eventKey] as Delegate;

        foreach(EventHandler item in eventHandler.GetInvocationList()) {
            ctrl.Load -= item;
        }

        ctrl.Load += ctrl_Load;
        foreach (EventHandler item in eventHandler.GetInvocationList()){
            ctrl.Load += item;
        }
        ctrl.Load += ctrl_Load;

        this.Controls.Add(ctrl);
    }

    void ctrl_Load(object sender, EventArgs e)
    {
        //throw new NotImplementedException();
    }
}

      

0


source







All Articles