Добавление обработчиков событий с помощью отражения - PullRequest
0 голосов
/ 17 декабря 2008

Я добавляю динамически элементы управления на страницу с помощью LoadControl и Controls.Add. Мне нужно как-то обернуть обработчики событий Init и Load этих загруженных элементов управления в мой код. Так должен быть такой порядок событий SomeMyCode () -> Control.Init () -> AnotherMyCode () и то же самое для Load SomeMyCode () -> Control.Load () -> AnotherMyCode () .
Моя идея состояла в том, чтобы получить список обработчиков событий Control для событий Init и Load и добавить первых и последних обработчиков событий с кодом, который я должен запустить. Но я не могу понять, как это сделать.

Ответы [ 2 ]

1 голос
/ 17 декабря 2008

Вы не можете принудительно внедрить обработчик события перед другими обработчиками, уже подписанными на событие. Если вам нужен метод A, который будет вызван первым, то сначала вам нужно подписаться на A.


Re ваш комментарий, это невероятно хак. Во-первых, вы даже не можете полагаться на событие, имеющее сторонника делегатского поля; это может быть EventHandlerList или другой - который не обязательно выставляет удобные крючки, за исключением изменения хода удаления.

Во-вторых (и это более важно), оно нарушает все правила инкапсуляции.

В общем, если вы хотите быть первым, подход best состоит в переопределении метода OnFoo(). Второй лучший - подписаться первым.

0 голосов
/ 17 декабря 2008

Вот черновик рабочего решения:

    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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...