2012-02-01 20 views
8

Hace un par de días publiqué una pregunta sobre viewstate y después de ejecutar algunas pruebas he llegado a algunas conclusiones/resultados. En base a estos resultados, tengo algunas preguntas sobre cómo alguien haría ciertas cosas.Viewstate and controls en ASP.NET

Éstos son los resultados de mis pruebas que me encontré:

  1. Si UserControlA se carga desde OnInit de una página, entonces su estado de vista estará disponible en OnLoad. Todos los demás controles que cargue usercontrolA desde OnInit, tendrán su viewstate listo en su OnLoad.
  2. Si usercontrolA se carga desde OnLoad de una página, su viewstate estará disponible en OnPreRender. El resto de los controles que usercontrolA carga desde su OnLoad, tendrán su viewstate disponible en su OnPreRender.
  3. Si usercontrolA se carga desde un evento (Ejemplo: botón de clic. Eventos desencadenados después de OnLoad y antes de OnPreRender) de una página, su viewstate no estará disponible. Todos los otros controles que usercontrolA loades no tendrán su viewstate disponible.

Por lo tanto, en un mundo perfecto siempre cargaría todos los controles utilizando la situación n. ° 1, de modo que su viewstate esté disponible en su OnLoad. Desafortunadamente, cuando necesita cargar un control desde un botón, haga clic o desde OnLoad, ¿no hay forma de que el control obtenga su estado de vista antes del paso OnPreRender?

He leído un montón de artículos sobre viewstate y pensé que lo entendía, pero trabajando en mi aplicación actual que carga controles de usuario que cargan otros controles de usuario, estoy teniendo un momento difícil para poder obtener viewstate en mi hoja (último en la cadena) usercontrol.

Se agradecen todas las sugerencias y/o enlaces.

Respuesta

3

Se acepta la práctica de cargar controles dinámicos en OnInit, de modo que obtengan el ciclo de vida de control completo. Sin embargo, no estoy seguro si entiendo tu situación en particular: si estás cargando un control basado en un clic de botón, ¿por qué tendría viewstate en ese punto? En el siguiente OnInit, debe cargar el control nuevamente (generalmente utilizo un elemento Viewstate de nivel de página para rastrear que un control particular necesita cargarse) para que pueda restaurar desde Viewstate. Algo así como:

class Default : Page { 
    enum LoadedControl { Textbox, Label, GridView } 

    override OnInit() { 
     if (IsPostback) { 
     var c = Viewstate["LoadedControl"] as LoadedControl; 
     if (c != null) LoadDynamicControl(c); 
     } 
    } 

    void Button_Click() { 
    var c = (LoadedControl)Enum.Parse(typeof(LoadedControl), ddl.SelectedValue); 
    LoadDynamicControl(c); 
    } 

    void LoadDynamicControl(LoadedControl c) { 
    switch (c) { 
     case LoadedControl.Textbox: 
      this.ph.Controls.Add(new Textbox()); 
      break; 
     ... 
    } 

    ViewState["LoadedControl"] = c; 
    } 
} 

El bit un poco más interesante, sin embargo, es que de acuerdo a ponerse al día eventos - lo que realmente no debería importar. La pila de llamadas para cargar dinámicamente un control se ve algo como:

Control.Controls.Add(Control) 
    Control.AddedControl(Control) 
     Control.LoadViewStateRecursive(object) 
      Control.LoadViewState(object) 

Tomando Label como ejemplo, se anula LoadViewState y tira de ella es Text propiedad directamente de ViewState. TextBox es similar. Por lo tanto, según mi lectura, debería estar bien agregar en cualquier momento y luego acceder a ViewState. Sin embargo, eso no parece estar relacionado con mi experiencia, por lo que una mayor investigación parece justificada.

+0

Hola, este fue uno de mis problemas por los que estaba tratando de usar viewstate. Necesitaba marcar de alguna manera que mi control debe cargarse en la próxima devolución de datos después de que fue cargado por un controlador onclick en la devolución de datos anterior. Estaba pensando en usar el viewstate de la página que tendrá los valores. En mis pruebas parece que este podría ser el camino a seguir. – BlueChameleon

1

me sorprende, pero interesados ​​acerca de sus resultados. Cuando trabajo con controles dinámicos, siempre los agrego en Page_Init. Cualquier otra cosa no funciona. Pero tiene razón, ¿cómo lo hace si los está agregando en respuesta a un clic de botón?

La única forma que he encontrado es examinando la colección Request.Form("__EVENTTARGET") en PageInit. Este contiene el ID de control del control que ha desencadenado la devolución de datos por lo que, por ejemplo, un clic de botón. Por supuesto, estará calificado por los contenedores de nombres en los que aparece. Una vez que haya identificado el 'evento' mediante este método, puede agregar los controles que desee.

Por supuesto, es un poco raro, pero es la única forma que encuentro de hacer estas cosas. Funciona.

Es interesante que el ViewState está disponible en PreRender si agrega los controles al Page_Load. Pero como el enlace de arriba indica que es demasiado tarde para ayudarte, entonces. El estado de los controles se rehidrata durante el ciclo de carga. Si no está allí, su estado de control o controles dinámicos simplemente desaparecerán.

+0

Creo que no puede diferenciar entre Viewstate disponible y persistir entre las devoluciones. Viewstate se carga desde las devoluciones anteriores durante Page.Load, lo que significa que si crea el control durante un controlador Page.Load, perderá la persistencia automática de su estado de visualización. – pseudocoder

0

¿Intentó utilizar el evento LoadComplete?

Utilice este evento para las tareas que requieren que se carguen todos los demás controles de la página.

Esta es despedido después de PageLoad y todos los eventos (ButtonClick, etc.), por lo que sus UserControls se están cargados en eventos ButtonClick, y en su LoadComplete ViewState ya se ha inicializado.

+0

Gracias por su respuesta, pero no estoy seguro de estarlo. Uno de los controles de usuario necesita obtener un valor de viewstate. LoadComplete está en el nivel de página. – BlueChameleon

+0

si quiere un evento donde sabe qué eventos de clic se han producido, LoadComplete es el primero. – Leon

Cuestiones relacionadas