Dynamic WebForms in ASP.NET : Javier Luna blog

Thursday, July 01, 2004

Dynamic WebForms in ASP.NET

Muchas veces, segun los requerimientos del cliente, se da la necesidad de poder construir -en ciertos casos- formularios webs y grillas de datos de manera dinamica, a partir de cierta logica para definir la estrucura que se ha de presentar a traves de la interfaz del usuario.

Les muestro un ejemplo que puede darles las primeras pautas de como poder llevar a cabo estas tareas.

Archivo .ASPX

<form id="SimpleDynamic" method="post" runat="server">
<asp:PlaceHolder id="_holder" runat="server"></asp:PlaceHolder><br/>
<asp:Button id="_submit" runat="server" Text="Submit"></asp:Button><br/>
<asp:Label id="_post" runat="server"></asp:Label><br/>
<asp:Label id="_message" runat="server"></asp:Label><br/>
</form>

--- End File ---


Notese el uso del control PlaceHolder, que permitira alojar en el diferentes tipos de controles en tiempo de ejecucion, para su posterior presentacion e interaccion.


Archivo .CS

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace DemoWebAppCSharp.Custom
{
/// <summary>
/// Descripción breve de Dynamic.
/// </summary>
public class SimpleDynamic : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button _submit;
protected System.Web.UI.WebControls.Label _message;
protected System.Web.UI.WebControls.Label _post;
protected System.Web.UI.WebControls.PlaceHolder _holder;

private void Page_Load(object sender, System.EventArgs e)
{
if( ! this.IsPostBack )
{
// Llenando el DropDownList de datos
this.FillList();
}
}

private void DefineForm()
{
TextBox Name = new TextBox();
Name.ID = "_name";

DropDownList List = new DropDownList();
List.ID = "_list";
List.AutoPostBack = true;

// Enganchando una funcionalidad al evento del DropDownList
List.SelectedIndexChanged += new EventHandler( this.List_SelectedIndexChanged );

// Colocando los controles en el PlaceHolder
this._holder.Controls.Add( Name );
this._holder.Controls.Add( List );
}

private void FillList()
{
// Solicitando el DropDownList al PlaceHolder
DropDownList List = (DropDownList)this._holder.FindControl( "_list" );

List.Items.Add( "-- Elija una opción --" );
List.Items.Add( "Simple Geek");
List.Items.Add( "Spoutlet" );
List.Items.Add( "Frabriq" );
}

// Funcion que se enganchara al evento correspondiente del DropDownList
private void List_SelectedIndexChanged( Object sender, EventArgs e )
{
DropDownList List = (DropDownList)sender;
this._post.Text = "Item selected: " + List.SelectedValue;
}

#region Código generado por el Diseñador de Web Forms
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Método necesario para admitir el Diseñador. No se puede modificar
/// el contenido del método con el editor de código.
/// </summary>
private void InitializeComponent()
{
this._submit.Click += new System.EventHandler(this.Submit_Click);
this.Load += new System.EventHandler(this.Page_Load);

this.DefineForm();
}
#endregion

// Posteando la informacion
private void Submit_Click(object sender, System.EventArgs e)
{
TextBox Name = (TextBox)this._holder.FindControl( "_name" );
DropDownList List = (DropDownList)this._holder.FindControl( "_list" );

this._message.Text = Name.Text + " : " + List.SelectedValue;
}
}
}

--- End File ---

Explicando, se contruira un TextBox y un DropDownList que esta seteado como AutoPostBack. De esta manera, cada vez que el usuario seleccione un item en la lista la pagina se posteara inmediatamente.

Revisando el metodo DefineForm. En este punto se muestra algo interesante, que es el enganche de un metodo hacia el evento de un control que se crea on-fly, es decir en tiempo de ejecucion.

Este metodo -el DefineForm- es llamado desde el InitializeComponent, que permite ejecutar operaciones sobre el metodo sobre-escrito OnInit. Que por cierto, es el lugar adecuado para poder colocar elementos dinamicos en la pagina.

Vale decir, que por el hecho de ser llamado desde dicho evento -el Init- la construccion dinamica de los elementos se realiza, por cada peticion de la pagina. Pues este evento siempre es solicitado por cada PostBack, al igual que el evento Load.

Es trabajo del modelo de objetos de ASP.NET, mantener el estado de los controles en la pagina por cada posterior PostBack.

Se remarca tambien, que los itemes adheridos al DropDownList, solo se realiza una sola vez, y esta operacion se lleva a cabo dentro del evento Load, validando el IsPostBack.

Se quiere dar a entender de esta manera, que la estructura del formulario es independiente de los datos que se plasmaran en dicha estructura. El evento Init es el lugar correcto para construir estructuras dinamicas y el Load para llenar datos en esas estructuras.

El metodo List_SelectedIndexChanged, solo hace un casting del objeto sender. Pues es justamente en esta variable que se encuentra una referencia al control que provoco el posting de la pagina, es decir el DropDownList.

Finalmente, el metodo Submit_Click, solicita al PlaceHolder, los controles que se adherieron al el, para presentar los valores que el usuario haya ingresado o seleccionado.

En conclusion, la intencion es poder construir cualquier estructura en el webform, a partir de una metadata, que brinde toda la informacion necesaria para la presentacion de dicha estructura y los datos que han de colocarse en el.

Les recomiendo descargar una interesante herramienta que he constuido, y que justamente parte de lo aqui mostrado es el 'core' de dicho producto.

http://groups.msn.com/mugperu/general.msnw?action=get_message&mview=1&ID_Message=11466

En dicho lugar, podran encontrar mayor informacion de como instalar el software y como trabajar con el.

Comparto tambien estos lugares de donde podran encontran mayor informacion sobre los eventos asociados a una pagina, el orden en el que son llamados y las actividades que se realizan en cada uno de ellos.

The ASP.NET Page Object Model
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/aspnet-pageobjectmodel.asp

The ASP.NET Page Life Cycle
http://www.15seconds.com/issue/020102.htm

Al igual que esto, la construccion de un DataGrid dinamico en funcion a las columnas y al contenido en cada DataGridItem, sean estos datos u otros controles, tambien es posible realizarlo, de esta forma.

Javier Luna
-- Software Architect and blogger too ;)
-- Movil: (51-1) 9-731-7187

"Indigo: Ports, Messages, Channels and more..."

2 comments:

Anonymous said...

Veo muy interesante esta aplicacion,pero no puedo descargarmela, puedes dar más información. Muchisimas gracias

Anonymous said...

Hola!!! Quisiera hacerte una pregunta. Estoy trabajando con visual basic 2005 y no se como declarar una variable publica para que despues la pueda utilizar desde otro web form. Si pudieras contestarme te lo agradeceria. Gracias!!!