En esta oportunidad vamos a incorporar un poco de comportamiento en la interfaz de usuario y los componentes de ADO.NET.
En la publicación anterior se mostró como se puede utilizar un componente de interfaz de usuario (en ese caso un GridView) y "llenarlo" desde el código asociado con los datos. Obviamente esto nos permite separar dos aspectos importantísimos del desarrollo de software (la presentación y la lógica); por supuesto todavía estamos muy lejos de una arquitectura en capas, pero vamos en camino.
El objetivo de esta publicación es relacionar componentes de la interfaz de usuario, vamos a utilizar la información de Provincias, Departamentos y Localidades (que pueden obtener en la parte 2 de esta serie). En este caso vamos a lograr que el usuario pueda seleccionar de varios DropDownList la información de Provincia, Departamento y Localidad que necesite, obviamente cuando el usuario selecciona una Provincia en el DropDownList de Departamentos solamente pueden aparecer los que correspondan a esa provincia, he ahí la relación entre los componentes de la interfaz de usuario y por supuesto el código que debe soportar ese comportamiento.
Para este ejercicio vamos a necesitar la base de datos Postal (que se creó en la publicación anterior), una nueva página o formulario web donde podemos poner una tabla de dos columnas y tres filas de manera que podamos organizar en la primer fila el texto o rótulo Provincias y en la celda contigua ponemos un DropDownList, lo mismo en las siguientes filas solo que para Departamentos y la última para Localidades.
El ejercicio lo vamos a realizar utilizando los asistentes que el Visual Studio nos facilita, de modo que la mayoría del código estará en el archivo .aspx (aunque no me gusta sirve como prototipo). Al DropDownList para las Provincias le asociamos un origen de datos que obtenga justamente las provincias de la base de datos.
Para el DropDownList de Departamentos vamos a indicar un origen de datos que deberá "filtrar" los registros de de datos, recuperando solamente aquellos departamentos que se correspondan con la Provincia actualmente seleccionada en el DropDownList de Provincias; obviamente haremos lo mismo para las Localidades.
El diseño del formulario puede ser algo así:

El código que genera el asistente para el caso del DropDownList de Provincias es el siguiente
<td>
<asp:DropDownList ID="ddlProvincia" runat="server" AutoPostBack="True"
DataSourceID="dsProvincia" DataTextField="Nombre" DataValueField="ID"
onselectedindexchanged="ddlProvincia_SelectedIndexChanged">
</asp:DropDownList>
<asp:SqlDataSource ID="dsProvincia" runat="server"
ConnectionString="<%$ ConnectionStrings:Postal %>"
SelectCommand="SELECT [ID], [Nombre] FROM [Provincia]"></asp:SqlDataSource>
</td>
Es muy sencillo, solamente se incorpora el nombre del método que atrapa el evento de cambio del índice de selección, el resto es lo normal.
Para el DropDownList de Departamentos tenemos lo siguiente:
<td>
<asp:DropDownList ID="ddlDepartamento" runat="server" AutoPostBack="True"
DataSourceID="dsDepartamento" DataTextField="Nombre" DataValueField="ID"
onselectedindexchanged="ddlDepartamento_SelectedIndexChanged">
</asp:DropDownList>
<asp:SqlDataSource ID="dsDepartamento" runat="server"
ConnectionString="<%$ ConnectionStrings:Postal %>"
SelectCommand="SELECT [ID], [Nombre] FROM [Departamento] WHERE ([idProvincia] = @idProvincia)">
<SelectParameters>
<asp:ControlParameter ControlID="ddlProvincia" Name="idProvincia"
PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
</td>
La cosa se complica un poquito; también se controlará el cambio del índice de selección. Pero en este caso el origen de datos utiliza una sentencia SQL que requiere de un parámetro, el que se obtiene de la propiedad SelectedValue del DropDownList de Provincia.
Para las Localidades es algo parecido:
<td>
<asp:DropDownList ID="ddlLocalidad" runat="server" AutoPostBack="True"
DataSourceID="dsLocalidad" DataTextField="Nombre" DataValueField="ID"
onselectedindexchanged="ddlLocalidad_SelectedIndexChanged">
</asp:DropDownList>
<asp:SqlDataSource ID="dsLocalidad" runat="server"
ConnectionString="<%$ ConnectionStrings:Postal %>"
SelectCommand="SELECT [ID], [Nombre] FROM [Localidad] WHERE ([idDepartamento] = @idDepartamento)">
<SelectParameters>
<asp:ControlParameter ControlID="ddlDepartamento" Name="idDepartamento"
PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
</td>
También se utiliza un parámetro que en este caso se obtiene de la propiedad SelectedValue del DropDownList de Departamentos.
De este modo los controles de la interfaz de usuario están enlazados unos con otros y la obtención de los datos se logra filtrando los mismos en la sentencia SQL apropiada.
En el caso de las Localidades se atrapa el evento de cambio de índice de selección solamente para poder mostrar los datos de la Localidad.
El código asociado a esta página .aspx solamente cuenta con los métodos que atrapan los eventos de cambio de índice de selección, donde se invoca al método .DataBind() del DropDownList correspondiente, de este modo se logra que los datos se actualicen cuando el usuario cambia las selecciones:
El siguiente es el código completo:
using System;
namespace ADO2
{
public partial class WebForm2 : System.Web.UI.Page
{
/// <summary>
/// Carga de la página
/// </summary>
/// <param name="sender">Referencia al objeto que ejecuta el evento</param>
/// <param name="e">Información del evento</param>
protected void Page_Load(object sender, EventArgs e)
{
}
/// <summary>
/// Atrapa el cambio de selección en el DropDownList (Provincia)
/// </summary>
/// <param name="sender">Referencia al objeto que ejecuta el evento</param>
/// <param name="e">Información del evento</param>
protected void ddlProvincia_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlProvincia.SelectedIndex != -1)
{
ddlDepartamento.DataBind();
lblResultado.Text = "";
}
}
/// <summary>
/// Atrapa el cambio de selección en el DropDownList (Departamento)
/// </summary>
/// <param name="sender">Referencia al objeto que ejecuta el evento</param>
/// <param name="e">Información del evento</param>
protected void ddlDepartamento_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlDepartamento.SelectedIndex != -1)
{
ddlLocalidad.DataBind();
lblResultado.Text = "";
}
}
/// <summary>
/// Atrapa el cambio de selección en el DropDownList (Localidad)
/// </summary>
/// <param name="sender">Referencia al objeto que ejecuta el evento</param>
/// <param name="e">Información del evento</param>
protected void ddlLocalidad_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlLocalidad.SelectedIndex != -1)
{
lblResultado.Text = "Seleccionó " + ddlLocalidad.SelectedValue + " - " + ddlLocalidad.SelectedItem.Text;
}
}
}
}
Observen que además de volver a enlazar los datos en los DropDownList se "borra" el label que muestra la selección final
Espero que les sirva, pero recuerden que están incorporando código de interfaz de usuario y código de acceso a datos en la misma capa; eso es aceptable en un prototipo pero no en un producto final.
Para leer fuera de línea: Un Poco de ADO NET - parte 3.pdf (61,38 kb)