Nonostante abbia lavorato con WebForms per anni, continuo a trovarmi confuso sul ciclo di vita degli eventi di tanto in tanto. Questo non è tanto un problema che deve essere risolto, quanto sperare di ottenere una migliore comprensione del perché le cose funzionano come loro.Perché i controlli secondari vengono inizializzati prima dei contenitori?
Supponiamo di avere una forma:
Default.aspx:
<form>
<MyControls:UserControl1 runat="server">
</form>
UserControl1: ascx:
<MyControls:UserControl2 runat="server">
Gli OnInit
eventi si verificano nel seguente ordine:
UserControl2_OnInit
UserControl1_OnInit
Default_OnInit
Non è solo un bass-ackwards? Non dovrebbe essere eseguito il codice Init nell'ordine in cui vengono creati i controlli? Non dovrebbe un controllo genitore essere in grado di inizializzare le proprietà di un figlio prima dell'esecuzione di OnInit? Cioè, mentre è possibile inizializzare le proprietà dei sottocontrolli nel markup, non esiste un modo diretto per consentire a un controllore principale di impostare dinamicamente le proprietà del controllo figlio che saranno disponibili per l'evento OnInit.
Quello che ho finito per fare è cose come questa:
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
}
Quindi non è un problema insormontabile. Solo non capisco perché è un problema, in primo luogo.
Mi rendo conto che forse potresti voler essere in grado di inizializzare tutti i controlli figlio nel tuo codice OnInit. Quindi, dovresti essere in grado di chiamare base.In prima, anziché dopo, il tuo codice di inizializzazione, che dovrebbe causare l'esecuzione di tutti gli eventi OnInit del controllo figlio. Ma il ciclo di vita dell'evento non funziona in questo modo. Gli eventi Init non sono concatenati in modo ricorsivo, sembrano eseguire indipendentemente gli eventi parent e il più interno viene sempre eseguito per primo. Ma sembra che la vita sarebbe molto più facile se fossero semplicemente incatenati in modo ricorsivo in modo da poter chiamare l'evento di base (o meno) prima di fare la tua cosa in una determinata situazione. C'è qualcosa che mi manca che rende questa situazione apparentemente controintuitiva desiderabile o addirittura necessaria?
Sono d'accordo con te poiché le classi base sono inizializzate prima dei loro figli. –
Non ho una risposta alla tua domanda, ma posso dirti che le linee guida sono che non devi fare affidamento sui contenitori genitore o figlio in questa fase del ciclo di vita. http://msdn.microsoft.com/en-us/library/system.web.ui.control.init.aspx –
Si tratta di ciò che ritengo sia un difetto di progettazione fondamentale nell'architettura dei Webform. Quindi non si suppone che si stabiliscano relazioni tra i controlli padre e figlio finché (suppongo) 'OnLoad'. Tuttavia, è spesso importante fare le cose prima di 'OnLoad', come ricreare i controlli che sono stati creati dinamicamente (che ms dice di fare in OnInit: http://support.microsoft.com/kb/317794 Quindi se hai bisogno di informazioni dal database per capire quale di questi controlli creare? Quindi, che cosa succede se la tua origine dati è determinata da un genitore? –