2008-09-22 20 views
9

Estoy intentando abarcar asp.net. Tengo experiencia como desarrollador de PHP desde hace mucho tiempo, pero ahora estoy enfrentando la tarea de aprender asp.net y estoy teniendo problemas con eso. Bien podría ser porque estoy tratando de forzar el marco en algo para lo que no está destinado, así que me gustaría aprender cómo hacerlo "de la manera correcta". :-)Controles añadidos dinámicamente en Asp.Net

Mi problema es cómo agregar controles a una página mediante programación en tiempo de ejecución. Por lo que puedo deducir, necesitas crear los controles en page_init, ya que de lo contrario desaparecerían en la próxima publicación de PostBack. Pero muchas veces me enfrento al problema de que no sé qué controles agregar en page_init ya que depende de los valores de PostBack anterior.

Un escenario simple podría ser un formulario con un control desplegable agregado en el diseñador. El menú desplegable está configurado en AutoPostBack. Cuando se produce el PostBack, necesito renderizar uno o más controles denegando el valor seleccionado del control desplegable y preferiblemente hacer que esos controles actúen como si hubieran sido añadidos por el diseño (como en "cuando se publiquen, se comporten" correctamente).

¿Voy por el camino equivocado aquí

+0

Creo que mucha gente aquí lo está guiando por el camino equivocado; aunque todas sus respuestas son técnicamente correctas, realmente no haría las cosas de esta manera. Demasiado complicado, en comparación con una solución más elegante como MultiView o algo así. – Domenic

Respuesta

8

Estoy de acuerdo con los otros puntos hechos aquí "Si se puede salir de la creación de controles dinámicamente , entonces hazlo ... "(por @Jesper Blad Jenson aka) pero aquí hay un truco que resolví con controles creados dinámicamente en el pasado.

El problema se convierte en el huevo y la gallina. Necesita su ViewState para crear el árbol de control y necesita su árbol de control creado para llegar a su ViewState. Bueno, eso es casi correcto. Hay una manera de obtener los valores de ViewState justo antes de el resto del árbol está lleno. Eso es anulando LoadViewState(...) y SaveViewState(...).

En SaveViewState almacenar el control que desea crear:

protected override object SaveViewState() 
{ 
    object[] myState = new object[2]; 
    myState[0] = base.SaveViewState(); 
    myState[1] = controlPickerDropDown.SelectedValue; 

    return myState 
} 

Cuando el marco llama a su "LoadViewState" anular que pondremos en el objeto exacto que regresó de "SaveViewState":

protected override void LoadViewState(object savedState) 
{ 
    object[] myState = (object[])savedState; 

    // Here is the trick, use the value you saved here to create your control tree. 
    CreateControlBasedOnDropDownValue(myState[1]); 

    // Call the base method to ensure everything works correctly. 
    base.LoadViewState(myState[0]); 
} 

Lo he usado con éxito para crear páginas ASP.Net donde un DataSet se serializó en ViewState para almacenar los cambios en una cuadrícula completa de datos que permite al usuario realizar múltiples ediciones con PostBacks y finalmente comprometer todos sus cambios en un solo " Guardar "operación.

+0

Esto parece una buena idea. Lo meditaré por un tiempo y veré si puedo adaptarlo a mi modo de pensar o tal vez al revés. :-) – mlarsen

+0

Error de error ... el objeto [0] debería ser myState [0] ... – Brij

+0

Buena captura @Brij. Corregido ahora, gracias. –

0

Bien Si puede salir de la creación de controles dinámicamente, y luego hacerlo? -. de lo contrario, lo que whould hago es utilizar Load en lugar de Page_Init, pero en lugar de colocando cosas dentro de If Not IsPostBack, luego configuré solo directamente en el método.

0

Creo que la respuesta aquí está en el control MultiView, de modo que, por ejemplo, los conmutadores desplegables apuestan ween diferentes puntos de vista en la vista múltiple.

¡Es probable que incluso pueda vincular datos a la propiedad de vista actual de la vista múltiple con el valor de la lista desplegable!

0

Ah, ese es el problema con la abstracción filtrada de los formularios web ASP.NET.

Quizás le interese consultar ASP.NET MVC, que se usó para la creación de este sitio web stackoverflow.com? Eso debería ser más fácil para usted, viniendo de un fondo PHP (por lo tanto, pedaleando hacia el metal cuando se trata de HTML y Javascript).

+0

Sí, ASP.NET MVC parece muy prometedor y está mucho más cerca de la forma en que estoy acostumbrado a trabajar. Lamentablemente, mis colegas tienen experiencia en el desarrollo de WinForms y no estoy seguro de poder convencerlos de que ASP.NET MVC es el camino a seguir. – mlarsen

3

Debe agregar su control dentro del evento OnInit y se conservará viewstate. No use if (ispostback), porque los controles deben agregarse cada vez, evento en la devolución de datos.
(De) La serialización de ViewState ocurre después de OnInit y antes de OnLoad, por lo que su proveedor de persistencia de viewstate verá los controles agregados dinámicamente si se agregan en OnInit.

Pero en el escenario que está describiendo, probablemente la vista múltiple o simple ocultar/mostrar (propiedad visible) será una mejor solución.
Es porque en el evento OnInit, cuando debe leer el menú desplegable y agregar nuevos controles, viewstate aún no se ha leído (deserializado) y usted no sabe qué eligió el usuario. (Se puede hacer request.form(), pero que se siente un poco mal)

1

Si realmente necesita usar controles dinámicos, lo siguiente debería funcionar:

  • En OnInit, recrear la misma jerarquía exacta de control que estaba en la página cuando se cumplió la solicitud anterior. (Si esta no es la solicitud inicial, por supuesto)
  • Después de OnInit, el marco cargará viewstate desde la solicitud anterior y todos sus controles deberían estar ahora en un estado estable.
  • En OnLoad, quite los controles que no son necesarios y agregue los necesarios.También deberá guardar de alguna manera el árbol de control actual en este punto, para usarlo en el primer paso durante la siguiente solicitud. Puede usar una variable de sesión que dicte cómo se creó el árbol de control dinámico. Incluso almacené toda la colección Controls en la sesión una vez (dejando de lado tus horcas, fue solo para una demostración).

Volver a agregar los controles "obsoletos" que no necesitará y que se eliminarán en OnLoad de todos modos parece un poco raro, pero Asp.Net no se diseñó pensando en la creación de controles dinámicos. Si la misma jerarquía de control no se conserva durante la carga del estado de visualización, en la página acechan todo tipo de errores difíciles de encontrar, porque los estados de los controles anteriores se cargan en los recién agregados.

Lea el ciclo de vida de la página Asp.Net y especialmente sobre cómo funciona el ViewState y será más claro.

Editar: Este es un artículo muy bueno sobre cómo estado de vista se comporta y lo que se debe tener en cuenta al tratar con los controles dinámicos: http://geekswithblogs.net/FrostRed/archive/2007/02/17/106547.aspx

0

La única respuesta correcta fue dada por Aydsman. LoadViewState es el único lugar para agregar controles dinámicos donde sus valores de viewstate se restaurarán cuando se vuelva a crear y podrá acceder al viewstate para determinar qué controles agregar.

0

me encontré con esto en el libro "Pro ASP.NET 3.5 en C# 2008" en la sección de control dinámico de creación:

Si es necesario volver a crear un control varias veces, se debe realizar la controlar la creación en el controlador de eventos Page.Load. Esto tiene la ventaja adicional de permitirle usar el estado de vista con su control dinámico. Aunque el estado de vista normalmente se restaura antes del evento Page.Load, si crea un control en el controlador para el evento Page.Load, ASP.NET aplicará cualquier información de estado de vista que tenga después de que finalice el controlador de eventos Page.Load. Este proceso es automático.

No he probado esto, pero es posible que lo analice.

2

Después de haber luchado con este problema por un tiempo, he llegado a estas reglas básicas que parece funcionar, pero YMMV.

  • Use controles declarativos siempre que sea posible
  • Uso de enlace de datos cuando sea posible
  • entender cómo ViewState funciona
  • La propiedad visibilidad puede recorrer un largo camino
  • Si tiene que usar agregar controles en una utilización controlador de eventos Consejo de Aydsman y recrear los controles en un LoadViewState reemplazado.

TRULY Understanding ViewState es una lectura obligada.

Understanding Dynamic Controls By Example muestra algunas técnicas sobre cómo utilizar enlaces de datos en lugar de controles dinámicos.

TRULY Understanding Dynamic Controls también aclara las técnicas que se pueden utilizar para evitar controles dinámicos.

Espero que esto ayude a otros con los mismos problemas.

+0

+1 especialmente "La propiedad Visibilidad puede recorrer un largo camino", me hizo darme cuenta de que puedo mantener mi problema más simple. –

Cuestiones relacionadas