A pesar de trabajar con WebForms durante años, todavía me encuentro confundido sobre el ciclo de vida del evento de vez en cuando. No se trata tanto de un problema que deba resolverse, sino de una mejor comprensión de por qué las cosas funcionan de la manera en que lo hacen.¿Por qué los subcontroles se inicializan antes que sus contenedores?
Suponga que tiene una forma:
Default.aspx:
<form>
<MyControls:UserControl1 runat="server">
</form>
UserControl1: ascx:
<MyControls:UserControl2 runat="server">
Los OnInit
eventos ocurren en este orden:
UserControl2_OnInit
UserControl1_OnInit
Default_OnInit
¿No es esto solo un bajo-ackwards? ¿No debería ejecutarse el código Init en el orden en que se crean los controles? ¿No debería un control principal poder inicializar las propiedades de un niño antes de que se ejecute OnInit? Es decir, aunque puede inicializar las propiedades de los subcontroles en el marcado, no hay una forma directa de que un control principal pueda establecer dinámicamente las propiedades del control secundario que estará disponible para su evento OnInit.
Lo que he terminado haciendo es cosas como esta:
override void UserControl2_OnInit()
{
NamingContainer.OnInit += new EvenHandler(UserControl1_ActualInit);
}
protected void UserControl2_ActualInit(..) {
// do actual init code here, which will occur before OnLoad but after it's parent
// OnInit
}
así que no es un problema insuperable. Simplemente no entiendo por qué es un problema en primer lugar.
Me di cuenta de que tal vez es posible que desee tener todos sus controles secundarios inicializados en su código OnInit. Tan bien, debería poder llamar a base.OnInit primero, en lugar de después, a su propio código de inicialización, que debería hacer que se ejecuten todos los eventos OnInit de control infantil. Pero el ciclo de vida del evento no funciona de esa manera. Los eventos Init no están encadenados recursivamente, parecen funcionar de forma independiente los eventos principales, y el más interno siempre se ejecuta primero. Pero parece que la vida sería mucho más fácil si simplemente estuvieran encadenados de manera recursiva, por lo que podría llamar al evento base (o no) antes de que haga lo suyo en cualquier situación dada. ¿Hay algo que me falta que hace que esta situación aparentemente contra intuitiva sea deseable o incluso necesaria?
Estoy de acuerdo contigo ya que las clases base se inicializan antes que sus hijos. –
No tengo una respuesta a su pregunta, pero puedo decirle que las pautas son que no debe confiar en contenedores para padres o niños en esta etapa del ciclo de vida. http://msdn.microsoft.com/en-us/library/system.web.ui.control.init.aspx –
Esto se reduce a lo que creo que es un defecto de diseño fundamental en la arquitectura de formularios web. Entonces no se supone que establezcas relaciones entre los controles padre e hijo hasta (supongo) 'OnLoad'. Sin embargo, a menudo es importante hacer cosas antes de 'OnLoad', como los controles de recreación que se han creado dinámicamente (lo que MS dice que hacer en OnInit: http://support.microsoft.com/kb/317794 Entonces, ¿qué sucede si necesita información? desde la base de datos para averiguar cuál de esos controles crear? Entonces, ¿qué pasa si tu fuente de datos es determinada por un padre? –