我通过使用LoadControl和Controls.Add向页面添加动态控件。我需要以某种方式将这个加载的控件的Init和Load事件处理程序包装到我的代码中。所以它应该是这样的事件顺序 SomeMyCode() - > Control.Init() - > AnotherMyCode()和Load SomeMyCode() - >相同Control.Load() - > AnotherMyCode()的。
我的想法是获取Init和Load事件的控制列表的事件处理程序,并添加我应该运行的代码的第一个和最后一个事件处理程序。但我无法弄清楚如何做到这一点。
答案 0 :(得分:1)
您无法在已订阅事件的其他处理程序前强行注入事件处理程序。如果您需要首先调用方法A,那么您需要首先订阅A.
重新发表你的评论,这真是令人难以置信的hacky。首先,您甚至不能依赖具有委托字段支持者的事件;它可以是EventHandlerList
或其他 - 它不会暴露出方便的钩子而不能逆转移除。
其次(更重要的是),它打破了封装的每一条规则。
通常,如果您想成为第一个,最佳方法是覆盖OnFoo()
方法。第二好的是先订阅。
答案 1 :(得分:0)
以下是工作解决方案的草稿:
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();
}
}