c# asp.net user-controls dynamically-generated

c# - asp.net agregó dinámicamente valores de ahorro de control de usuario después de la devolución de datos



user-controls dynamically-generated (7)

Creo que lo que puede estar pasando es que cuando haces clic en el botón para agregar, los fuegos de Page_Load te crean una nueva página. Luego, el método de clic de botón agrega el control y la página termina la representación. Cuando hace clic por segunda vez, Page_Load crea su página y el método de clic de botón crea nuevamente un control y lo agrega a la página. Lamentablemente, el que agregó anteriormente ya no está allí.

¿Qué pasa si agregaste los controles a un repetidor? El estado de vista del repetidor puede hacer un seguimiento de cada control que agregue para que en la devolución posterior, no se desvanezca.

Aquí está mi problema. Tengo un control de usuario que quiero permitir a los usuarios agregar tantas instancias como sea necesario usando un clic de botón (cada vez que se hace clic en un botón, quiero agregar otra instancia de mi control de usuario a un Panel). Funciona bien la primera vez, pero cada publicación posterior adicional elimina todos los controles agregados. No tengo problemas para hacer un seguimiento de la cantidad de controles de usuario que ha agregado un usuario, pero ¿cómo me aseguro de que se mantengan en el mismo estado en que se encontraban antes de la devolución de datos? He leído algunas publicaciones sobre personas que usan SaveViewState y LoadViewState, pero no he podido encontrar ningún ejemplo.

Mi mayor problema es asegurar que todos los cuadros de texto y las listas desplegables de cada control de usuario permanezcan llenos con el mismo texto / valor / datos seleccionados después de cada publicación.

Gracias de antemano, Ben


Dado que está programando agregar controles a su página, deberá volver a crearlos en CADA postback.

Además, es necesario que recree controles agregados por programación en el evento PreInit o Init de la página. Esto es para el estado de visualización correcto que restablece la gestión de eventos.

Si no lo haces, el control se eliminará de la devolución de datos y no administrarán ningún evento.

EDITAR

Aunque se recomienda agregar dinámicamente controles en PreInit o Init , es cierto (como dice Dustin Hodges) que puede funcionar si los agrega en page_load . Diría que debes evitarlo a menos que no tengas otra opción.

Es posible que pueda salirse con la carga de sus controles en el controlador de eventos Page_Load y mantener el estado de la vista correctamente.
Todo depende de si está estableciendo programáticamente propiedades de los controles cargados dinámicamente y, si es así, cuándo lo hace en relación con la línea Controls.Add (dynamicControl).
Una discusión exhaustiva de esto está un poco más allá del alcance de este artículo, pero la razón por la que puede funcionar es porque el método Add () de la propiedad Controls carga recursivamente el estado de vista del padre en sus elementos secundarios, aunque la etapa de estado de la vista de carga haya pasado.

Fuente MSDN


Es una solución desagradable si tienes muchos usuarios, pero podrías incluir los controles de usuario en la sesión. Lo hago con el control de mi pie de página porque no quiero golpear el db cada vez que la página cambia para recrear el pie de página.

Estas soluciones pueden realmente imponer tareas en el servidor si tiene muchos usuarios y usan mucho esta función. Al menos creo que lo hará ...

Pero puede volver a llenar su marcador de posición que tiene los controles de usuario en page_load. Puedo poner un ejemplo en breve.

Ejemplo de lo que hago:

if (Session["footer"] == null) { Session["footer"] = new Footer(LinksRules.BuildFooterLinks((int)WebSiteSections.Main));// where Footer is my control } footerPH.Controls.Add((Footer)Session["footer"]);

Como un patrón singleton tipo de ...

Entonces, como yo lo veo, puedes hacer esto en cualquier cosa que cause una devolución de datos

Session ["DynamicControls"] = PlaceHolder.Controls;

y en el método de cargar página puede:

foreach(var control in (List<Controls>)Session["DynamicControls"]) { yourPlaceHolder.Controls.Add(control); }

y si el objeto de la sesión es nulo simplemente agregue uno solo como si nunca hubieran estado allí.

Creo que esto dependerá de los datos dentro de los controles como lo desee.


Mire su PageLoad y agregue if(!this.IsPostBack) antes de la línea donde borra el panel.

esto es, por supuesto, solo una suposición, pero he visto muchas preguntas donde el problema estaba relacionado con esto .


Si realiza un seguimiento de la cantidad de controles que el usuario ha agregado, debe volver a crear los controles que el usuario agregó anteriormente, preferiblemente en Page_Init o Page_Load. Agregue algo como esto a ese controlador:

for(int i=0; i<NumberOfControlsUserHasAdded; i++) { //todo: change this to the appropriate user control TextBox tb = new TextBox(); tb.ID = "tb" + i.ToString(); //todo: add to appropriate control collection this.Controls.Add(tb); }

Si lo hace de esta manera, se debe mantener el estado de los controles porque cuando agrega el control tb a una colección de controles, se pone al día con los eventos y debe restaurar automáticamente su viewstate.

No debería tener que hacer un seguimiento de su estado en sesión, ya que en la mayoría de los casos se almacenará en viewstate para usted


Tuve una pesadilla de tiempo tratando de llevarlo a cabo en un viejo proyecto. En el tiempo intermedio, descubrí que sé mucho menos sobre desarrollo web de lo que pensaba (leer este sitio web es una gran manera de humillarse a diario, si no cada hora). En ese proyecto, Page.IsPostBack fue totalmente inútil para mí porque había creado una instancia dinámica de los controles.

Dicho esto, lo mejor que puedo sugerir es considerar el uso de la variable Session. Si tiene una clase (o una colección de una clase) que represente los datos que captura de la página, entonces quizás sería más fácil almacenar valores en esa clase / colección para mejorar la legibilidad del código, y luego escribirlo en la clase. Sesión.