Introducción
El desarrollo modular de aplicaciones web requiere la confección de componentes que permitan encapsular ciertos compartimientos que serán reutilizados, o que necesitan ser tratados de una forma unificada para facilitar la mantenibilidad del desarrollo.
Es por eso que en ciertas ocasiones el uso de User Controls es una buena práctica, aunque un aspecto no menor es la comunicación entre estos componentes encapsulados con el resto de la aplicación, o con otros componentes.
En este texto explicare como lograr la comunicación entre dos User Control, pasando datos de uno a otro de una forma desacoplada.
Diseño
El planteo se basará en la utilización de dos users control muy simples que estarán contenidos en una misma página web.
El primer user control encapsulará una grilla la cual cargara un listado de empleados.
El segundo contiene una serie de Textbox que serán utilizados para visualizar el registro seleccionado del primer user control.
User Control – Listado
Este estará formado por un control GridView.
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; namespace WebUserControlsCommunicated { public partial class ucGrid : System.Web.UI.UserControl { public delegate void GridSelectorCommandEventHandler(GridSelectorCommandEventArgs e); public event GridSelectorCommandEventHandler GridSelectorChanged; public class GridSelectorCommandEventArgs { public int Id { get; protected set; } public string Nombre { get; protected set; } public string Cargo { get; protected set; } public GridSelectorCommandEventArgs(int id, string nombre, string cargo) { this.Id = id; this.Nombre = nombre; this.Cargo = cargo; } } public DataTable DataSource { get; set; } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { GridView1.DataSource = this.DataSource; GridView1.DataBind(); } } protected void GridView1_SelectedIndexChanged(object sender, EventArgs e) { int Id = Convert.ToInt32(GridView1.SelectedRow.Cells[1].Text); string nombre = Convert.ToString(GridView1.SelectedRow.Cells[2].Text); string cargo = Convert.ToString(GridView1.SelectedRow.Cells[3].Text); if (GridSelectorChanged != null) GridSelectorChanged(new GridSelectorCommandEventArgs(Id, nombre, cargo)); } } }
Los puntos importantes a destacar del código serian:
- línea 30, define la propiedad que permitirá asignar el origen de datos que se usará para cargar el GridView. Esta propiedad será utilizada en el evento Page_Load del user control, asignando el contenido.
- líneas 12 y 13, en las mismas se define el handler y evento que permitirán que la información de los items seleccionados del GridView viajen desde el interior del user control hacia la página.
- líneas 15-27, definen el argumento del evento que será usado para realizar el pasaje de los datos seleccionados en la grilla. Es por medio de este argumento que se podrá recuperar los valores elegidos, ya que desde fuera del user control no se tendra acceso directo al GridView.
Habría una alternativas a esta opción, la cual consiste en dejar disponible en una propiedad los valores seleccionados, imitando un poco a las propiedades como ser el SelectedRow, o SelectedItems que poseen otro controles.
- líneas 42-53, estas defines el evento local al user control que se ejecutará al utilizar el botón de selección del GridView, básicamente será una especie de conversión de eventos, en donde un evento atrapado localmente, es transformado en un evento exterior, el cual es lanzado en la línea 50.
Como ser observara las primeras acciones son las de recuperar los valores de la columnas de la fila seleccionada, para poderlos usar como parámetros del argumento del evento que se lanzara.
Es muy importante cuando se va a lanzar un evento validar que este tenga algún método adjunto, ya que de no tener ninguno y ejecutarse este producirá un fallo, la validación por distinto de null evita este problema.
User Control – Listado de TextBox
Este user control contendrá una serie de TextBox, destinado a la visualización de la información seleccionada en el user control que contiene el GridView
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebUserControlsCommunicated { public partial class ucTextView : System.Web.UI.UserControl { public int Id { get; set; } public string Nombre { get; set; } public string Cargo { get; set; } protected void Page_Load(object sender, EventArgs e) { } public void Refresh(int id, string nombre, string cargo) { this.Id = Id; this.Nombre = nombre; this.Cargo = cargo; this.Refresh(); } public void Refresh() { txtId.Text = Convert.ToString(this.Id); txtNombre.Text = this.Nombre; txtCargo.Text = this.Cargo; } } }
Este control tiene bastante menos lógica que implementar ya que su funcionalidad se reduce a recibir los valores y asignarlos a los TextBox que correspondan.
Como se observa cuenta con una serie de propiedades que representan cada atributo de la entidad.
Y un método Refresh() que será el encargado de realizar en concreto la asignación de cada propiedad con su respectivo control.
Integración – Default.aspx
Bien llego el momento de poner todo en conjunto a funcionar.
Para ello se hará uso del formulario web, Default.aspx, es allí donde se arrastrara cada user control en el diseñador de la pagina, haciendo uso de una tabla para dar algo de formato y ubicación.
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; namespace WebUserControlsCommunicated { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { ucGrid1.GridSelectorChanged += new ucGrid.GridSelectorCommandEventHandler(ucGrid1_GridSelectorChanged); if (!IsPostBack) { ucGrid1.DataSource = CargarTabla(); } } void ucGrid1_GridSelectorChanged(ucGrid.GridSelectorCommandEventArgs e) { ucTextView1.Id = e.Id; ucTextView1.Nombre = e.Nombre; ucTextView1.Cargo = e.Cargo; ucTextView1.Refresh(); } private DataTable CargarTabla() { DataTable dt = new DataTable(); dt.Columns.Add("Id"); dt.Columns.Add("Nombre"); dt.Columns.Add("Cargo"); DataRow row = dt.NewRow(); row["Id"] = 1; row["Nombre"] = "Andres"; row["Cargo"] = "Developer"; dt.Rows.Add(row); row = dt.NewRow(); row["Id"] = 2; row["Nombre"] = "Federico"; row["Cargo"] = "PM"; dt.Rows.Add(row); row = dt.NewRow(); row["Id"] = 3; row["Nombre"] = "Leonardo"; row["Cargo"] = "Developer"; dt.Rows.Add(row); return dt; } } }
En la línea 14 es donde se define la utilización del evento expuesto por el user control que contiene la grilla, la asignación del handler requiere de un método declarado en las líneas 22-29.
Es en este método ucGrid1_GridSelectorChanged donde se hará uso de los parámetro del argumento del evento GridSelectorCommandEventArgs, para especificar los datos al segundo user control.
Como se habrá notado en este caso se asignan las propiedades directamente al segundo user control, para llamar por ultimo el método Refresh() que realizara la asignación de estos valores dentro del control; pero también se podría haber utilizado para tal fin el método Refresh() sobrecargado con los valores de cada propiedad necesaria para desplegar la información.
[C#] |