2010-02-12 18 views
6

Tengo un problema con ViewState. Tengo una página aspx que tiene una vista de árbol a la izquierda y un Panel de actualización con un panel ASP.NET adentro a la derecha. Es en ese Panel interno donde cargo y descargo dinámicamente los controles de usuario. Yo uso ese panel de actualización para cargar controles dinámicamente.Viewstate variable perdido en el control del usuario cargado dinámicamente

También hice un control personalizado para mis controles de usuario porque necesito pasar algunos valores de la página. En ese constructor utilizo ViewState para almacenar estos valores.

La primera vez que cargo el control de usuario llamo a su constructor con los parámetros. Cuando vuelvo a cargar ese control de usuario en cada devolución, utilizo su constructor normal.

Mi problema es que los valores que he almacenado en ViewState se han vuelto nulos en la devolución de datos sucesiva.

Actualización:

Este es un pedazo de mi control de usuario:

public class MyUserControl : System.Web.UI.UserControl 
{ 
private int PKId 
{ 
    get { return ViewState["pkId"] as int; } 
    set { ViewState["pkId"] = value; } 
} 

public MyUserControl(int pkId) 
{ 
    this.PKId = pkId; 
} 

... 
} 

estoy siguiendo este artículo para cargar dinámicamente controles: http://msdn.microsoft.com/en-us/magazine/cc748662.aspx#id0070065.

Segunda Actualización:
I también ajustar el mismo ID de control cuando la carga del control de usuario en la primera vez y en cada reaload.

Tal vez pueda usar otro método para almacenar estos valores como campos ocultos de entrada o Caché. Elegí ViewState porque no quiero sobrecargar el servidor con valores de sesión para cada usuario.

Tercera actualización:

I load the controls with this code: 

System.Web.UI.UserControl baseControl = LoadControl(ucUrl) as System.Web.UI.UserControl; 
if (baseControl != null) 
{ 
    baseControl.ID = "DestinationUserControl"; 
    PanelDestination.Controls.Add(baseControl); 
} 

Y reaload con este código:

DynamicControls.CreateDestination ud = this.LoadControl(TrackedUserControl) as DynamicControls.CreateDestination; 
if (ud != null) 
{ 
    ud.ID = "DestinationUserControl"; 
    PanelDestination.Controls.Add(ud); 
} 

¿Qué está pasando?

+0

Proporcione algunos de los códigos que lo están haciendo para que podamos tener una mejor idea de lo que está sucediendo. –

+0

He actualizado la pregunta. – VansFannel

+0

¿Por qué lo escribe como UserControl en la carga inicial y como CreateDestination en la carga? –

Respuesta

3

Intente almacenar el control en una variable local una vez que se haya cargado/construido antes de agregarlo a la jerarquía de control. Eso permite que los datos de ViewState sean mapeados desde y hacia el control. Ver "Regla 2" aquí http://chiragrdarji.wordpress.com/2009/05/20/maintain-viewstate-for-dynamic-controls-across-the-postback/.

+0

Configuré la misma ID en ambos casos y no funciona. – VansFannel

+1

Ah, vale. Mi respuesta esta actualizada Esto debería hacerlo. –

+0

Quizás no entiendo su respuesta, pero lo hago de la misma manera que en la Regla 2. Actualicé mi pregunta con más detalles. – VansFannel

0

Agregar controles dinámicamente dentro de un UpdatePanel es una mala idea. Genera muchos problemas.

Si es posible, mueva la creación del control dinámico fuera del UpdatePanel y creo que su problema se resolverá.

+0

Lo siento mucho. Cometí un error. Es un UpdatePanel con un panel ASP.NET adentro. Es en ese Panel interno donde cargo y descargo dinámicamente los controles de usuario. – VansFannel

3

¿Cuándo está cargando el control de usuario? Esto tiene que suceder en el evento Init si desea que ViewState se guarde/restaure.

+0

El control de usuario tiene algunos cuadros de texto. Si tienen algo de texto, se restaura correctamente en las devoluciones. Estoy recargando el control del usuario en el evento Page_Load. Estoy siguiendo este artículo para cargar los controles dinámicamente: http://msdn.microsoft.com/en-us/magazine/cc748662.aspx#id0070065 – VansFannel

+2

Si ese artículo dice que cargue controles dinámicos en Page_Load, es completamente erróneo. Esto funcionará en algunos casos, pero ciertamente no en todos, como has descubierto. La restauración de ViewState ocurre antes de Page_Load, y esa es la razón por la cual su variable es nula. No hay una forma más simple de explicarlo. – Bryan

0

Como se mencionó Bryan, debe cargar los controles dinámicos en Page_Init en lugar de Page_Load.

Como this description of the Page Life Cycle explica, para cuando se produce el evento Page_Load, el estado de vista de la devolución de datos ya se ha procesado (en PreLoad). Si los controles aún no se han vuelto a cargar, el estado de vista no tiene dónde ir.

Precarga:

Utilice este evento si es necesario realizar procesamiento en su página o control antes del evento de carga.

Antes de la instancia de página provoca este evento , se carga el estado de vista para sí y todos los controles, y luego procesa ningún datos de devolución incluidos con la instancia de solicitud .

+0

Tal vez pueda usar otro método para almacenar estos valores, como ingresar campos ocultos o Caché. Elegí ViewState porque no quiero sobrecargar el servidor. – VansFannel

+0

Los controles se pueden agregar dinámicamente en la devolución de datos en el evento Load, en cuyo momento su ciclo de vida se "pondrá al día" con el evento actual. Consulte "Eventos de actualización para controles agregados" aquí http://msdn.microsoft.com/en-us/library/ms178472.aspx y Tutorial n.º 6 aquí http://www.codeproject.com/KB/aspnet/ aspnetviewstatepagecycle.aspx # Tutoriales (que ilustra de manera excelente la diferencia en el comportamiento antes y después de agregar un control a la jerarquía). –

+0

@gWiz, mientras que el tutorial n. ° 6 es interesante, dependiendo de los eventos de "puesta al día" es problemático en el mejor de los casos. Incluso el tutorial mismo dice "se recomienda que agregue sus controles dinámicos durante los eventos" PreInit "o" Init "". Eso es lo que sugerí a @VansFannel. –

Cuestiones relacionadas