2009-11-20 3 views
6

Nella mia applicazione ASP.NET, sto caricando un .ascx utilizzando in modo dinamico LoadControl, utilizzando il seguente schema:Viewstate di ascx perde tra i postback

var ctrl = LoadControl("/path/to/control.ascx"); 
((ControlType)ctrl).SomeProperty = someData; 
placeholder.Controls.Add(ctrl); 

Il controllo che aggiungo salva il valore della proprietà SomeProperty direttamente a ViewState, come segue:

public int? SomeProperty 
{ 
    get { return (int?)ViewState["SomeProperty"]; } 
    set { ViewState["SomeProperty"] = value; } 
} 

Dopo di che, il controllo ascx vive una vita da solo e tutto va bene finché non si verifica postback. Quando la pagina torna indietro, improvvisamente lo stato della vista è vuoto! Sospetto che ciò accada perché manipolo il ViewState prima di aggiungere l'ascx istanziata alla mia pagina. Inoltre, posso evitare che il ViewState di perdersi aggiungendo la seguente riga nel metodo del mio controllo ascx Page_Load():

SomeProperty = SomeProperty; 

devo fare quanto sopra per ogni proprietà per garantire che il ViewState è conservato. Ora, c'è un modo più carino per farlo? Manipolare il ViewState dopo che l'hash istante è stato aggiunto alla pagina non è un'opzione - Ho bisogno del contenuto di ViewState nei metodi Page_Init() e Page_Load(), che vengono attivati ​​nell'istante in cui aggiungo l'.ascx alla mia pagina.

Grazie.

+0

Ho riscontrato un problema simile una volta, e nel mio caso il problema era che nel nostro tavolo di tutti i tempi, abbiamo impostato tutti i controlli su non utilizzare viewstate. Il mio punto è che aggiungere controlli dinamicamente potrebbe non essere necessariamente il problema, ma luoghi nascosti in cui viewstate è disabilitato. –

risposta

13

Date un'occhiata al ASP.NET Page Life Cycle e Understanding View State. View State viene caricato dopo l'inizializzazione, quindi non potrai accedervi in ​​Page_Init. Faresti meglio a usare un campo nascosto.

Se l'utente è morto impostato su Visualizza stato, il primo che si può ottenere sarà ignorando il metodo LoadViewState (Ricordarsi di chiamare base.LoadViewState prima di provare ad accedervi).

+0

+1 buoni riferimenti con spiegazione –

+0

Grazie, questo lo ha chiarito. Ora mi trovo di fronte a un dilemma: ho bisogno di creare alcuni controlli in Page_Init, a seconda del contenuto dello stato di visualizzazione (o del campo nascosto, del resto, che non sembra essere stato caricato in Page_Init). –

+0

Ohh se si va con l'approccio Hidden Field è necessario cercare in 'Request.Forms' il valore. Il controllo effettivo del server non verrà ancora caricato. Provaci. – Bob

1

tenere traccia del ID di UserControl prima di postback poi postback ri-creare il controllo e assegnare l'ID di nuovo e dovrebbe caricare automaticamente il ViewState indietro nel.

+0

Oh, sì, ho dimenticato di dirlo. Ricreo effettivamente il controllo utente su ogni postback e mi assicuro che l'ID sia lo stesso ogni volta. Il problema non è che il ViewState non possa essere ripristinato, è che le modifiche allo stato di visualizzazione tra LoadControl e placeHolder.Controls.Add non vengono mantenute a meno che non ripeto esplicitamente le modifiche dopo che il controllo è stato aggiunto alla pagina. –

3

È inoltre necessario aggiungere il controllo alla raccolta di controlli PRIMA di impostare la proprietà. ViewState non viene registrato fino a quando non viene aggiunto alla raccolta di controlli.

placeholder.Controls.Add(ctrl); 
((ControlType)ctrl).SomeProperty = someData;