El Libro del Día: 2014-10-25
Titulo: La Biblia de Visual Basic .NET (Capítulo 5)
Autor: Luis Dueñas Huaroto
Editorial: Coredise
Nro Paginas: 112
Capítulo 5: Desarrollando Aplicaciones Web con ASP .NET
1. Trabajando con el Formulario y los Controles Web
1.1. Introducción a ASP .NET
1.2. Creando un Simple Sitio Web
1.3. Usando Controles Web Intrínsecos
1.4. Usando Controles Web de Imágenes
1.5. Usando el Control FileUpload y Controles de Validación
2. Mejorando el Diseño y Navegabilidad del Sitio Web
2.1. Creando y usando Hojas de Estilos en Cascada
2.2. Paginas Principales y Controles de Navegación
2.3. Usando Controles de Vistas MultiView y Views
3. Usando el Control GridView
3.1. Personalizando Columnas en el GridView
3.2. Paginando en el GridView
3.3. Ordenando en el GridView
3.4. Mantenimiento de Datos en el GridView
4. Creando Plantillas en Controles Enlazados a Datos
4.1. Trabajando con el Control Repeater
4.2. Trabajando con el Control DataList
4.3. Creando Plantillas Jerárquicas
Descarga:
Biblia_VisualBasicNET_Capitulo5
Blog de Luis Dueñas dedicado a la difusión del Desarrollo en Microsoft .NET, Visual Studio, WinForms, WebForms, MVC, ASP .NET, jQuery, AJAX, HTML5, JavaScript, Móviles, etc. Encontrarás Libros, Demos, Artículos Técnicos, Entrenamiento.
Mostrando las entradas con la etiqueta DataList. Mostrar todas las entradas
Mostrando las entradas con la etiqueta DataList. Mostrar todas las entradas
sábado, 25 de octubre de 2014
El Libro del Día: La Biblia de Visual Basic .NET (Cap 5)
Etiquetas:
ASP.NET,
Controles,
Coredise,
CSS,
DataList,
FileUpload,
GridView,
La Biblia,
Lduenas,
Libros,
Luis Dueñas Huaroto,
Master Pages,
MultiView,
Plantillas,
Repeater,
Validación,
Views,
Visual Basic .NET,
WebForms
miércoles, 6 de agosto de 2014
El Demo del Día: Paginar, Ordenar y Filtrar en el Control Web DataList
Paginar, Ordenar y Filtrar en el Control Web DataList
Requerimientos
Se desea crear una Aplicación Web que permita listar los datos de los empleados que cumpla con lo siguiente:
- Presente en forma de ficha la información del código, apellido, nombre y fecha de nacimiento del empleado.
- Muestre en la ficha la foto del empleado la cual se encuentra en un carpeta "Empleados" donde el nombre del archivo esta compuesto por el código del empleado y la extensión jpg. Para los archivos que no se encuentren se usará el archivo No.jpg.
- Las fichas deben tener fondo gris claro, pero al pasar el mouse el estilo de la ficha cambiara a fondo amarillo.
- La información debe estar paginada (por defecto mostrar 6 registros de empleados), mediante botones de desplazamiento y enlaces con números de paginas.
- Se debe permitir ordenar los registros por cualquier campo en forma ascendente y descendente.
- Se debe permitir filtrar los registros por cualquier campo ingresando el dato buscado.
Solución
Usaremos el control DataList con Plantilla de Datos para poder presentar en forma de ficha la información del empleado y mostrarla en varias columnas. Ademas agregaremos botones y enlaces para paginar, combos para seleccionar los criterios de ordenación y filtro de registros.
Nota: En este caso si podemos deshabilitar el ViewState del DataList ya que no hay ningun control dentro de la plantilla que haga PostBack, es decir enviaremos el minimo HTML al navegador en el cliente.
Crear el Procedimiento Almacenado en la Base de Datos de SQL Server
Usaremos la tabla Empleados (Employees) de Northwind:
Create Procedure [dbo].[uspEmployeesListar]
As
Select EmployeeID,LastName,FirstName,
IsNull(BirthDate,'1/1/1900') As BirthDate
From Employees Order By 1
Crear una Librería de Clases con las Entidades del Negocio
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.EntidadesNegocio" y modificar el código de la clase como sigue:
using System;
namespace Northwind.Librerias.EntidadesNegocio
{
public class beEmpleado
{
public int IdEmpleado { get; set; }
public string Apellido { get; set; }
public string Nombre { get; set; }
public string NombreCompleto
{
get
{
return (String.Format("{0} {1}",Nombre,Apellido));
}
}
public DateTime FechaNacimiento { get; set; }
}
}
Crear una Librería de Acceso a Datos
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.AccesoDatos" y modificar el código de la clase como sigue:
using System;
using System.Data; //CommandType
using System.Data.SqlClient; //SqlConnection, SqlCommand, SqlDataReader
using System.Collections.Generic; //List
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
namespace Northwind.Librerias.AccesoDatos
{
public class daEmpleado
{
public List<beEmpleado> listar(SqlConnection con)
{
List<beEmpleado> lbeEmpleado = null;
SqlCommand cmd = new SqlCommand("uspEmployeesListar", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader drd = cmd.ExecuteReader(CommandBehavior.SingleResult);
if (drd != null)
{
lbeEmpleado = new List<beEmpleado>();
int posIdEmpleado = drd.GetOrdinal("EmployeeID");
int posApellido = drd.GetOrdinal("LastName");
int posNombre = drd.GetOrdinal("FirstName");
int posFechaNacimiento = drd.GetOrdinal("BirthDate");
beEmpleado obeEmpleado;
while (drd.Read())
{
obeEmpleado = new beEmpleado();
obeEmpleado.IdEmpleado = drd.GetInt32(posIdEmpleado);
obeEmpleado.Apellido = drd.GetString(posApellido);
obeEmpleado.Nombre = drd.GetString(posNombre);
obeEmpleado.FechaNacimiento = drd.GetDateTime(posFechaNacimiento);
lbeEmpleado.Add(obeEmpleado);
}
drd.Close();
}
return (lbeEmpleado);
}
}
}
Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio.
Crear una Librería de Reglas del Negocio
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.ReglasNegocio" y modificar el código de la clase como sigue:
using System;
using System.Configuration; //ConfigurationManager
namespace Northwind.Librerias.ReglasNegocio
{
public class brGeneral
{
//Propiedad
public string Conexion { get; set; }
//Constructor
public brGeneral()
{
Conexion = ConfigurationManager.ConnectionStrings["conNW"].ConnectionString;
}
}
}
Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio, a la Librería de Acceso a Datos y a System.Configuration.
Agregar otra clase llamada: "brEmpleado" y escribir el siguiente código:
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Northwind.Librerias.EntidadesNegocio;
using Northwind.Librerias.AccesoDatos;
namespace Northwind.Librerias.ReglasNegocio
{
public class brEmpleado:brGeneral //Herencia
{
public List<beEmpleado> listar()
{
List<beEmpleado> lbeEmpleado = null;
using (SqlConnection con = new SqlConnection(Conexion))
{
try
{
con.Open();
daEmpleado odaEmpleado = new daEmpleado();
lbeEmpleado = odaEmpleado.listar(con);
}
catch (SqlException ex)
{
//Capturar el error y grabar un Log
}
} //con.Close(); con.Dispose(); con = null;
return (lbeEmpleado);
}
}
}
Nota: La clase "brEmpleado" hereda de la clase "brGeneral" la cadena de conexión para no pasarla como parámetro en cada método de la clase o en el constructor de cada clase se hace una sola vez.
Crear una Librería de Código de Usuario para Web
Crear un proyecto de tipo Librería de Clases en C# llamado: "General.Librerias.CodigoUsuarioWeb" y modificar el código de la clase como sigue:
using System;
using System.Collections.Generic;
using System.IO; //File
using System.Web; //HttpContext
namespace General.Librerias.CodigoUsuarioWeb
{
public class Imagen
{
public static string obtenerUrl(int id, string carpeta)
{
string archivo = HttpContext.Current.Server.MapPath
(String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id));
string url = String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id);
if (!File.Exists(archivo)) url = String.Format("../Imagenes/{0}/No.jpg", carpeta);
return (url);
}
}
}
Nota: Como esta librería va a ser usada por paginas web hay que hacer referencia a: "System.Web"
Crear la Aplicación Web en ASP .NET Web Form
Crear un "Nuevo Sitio web vacío de ASP .NET" en C# llamado "Demo14" y crear las siguientes carpetas:
- Estilos: Para el archivo de hoja de estilo (CSS).
- Imagenes. Dentro crear otra carpeta llamada "Empleados" y adjuntar los archivos con las fotos de los empleados: 1.jpg, 2.jpg, 3.jpg, ... y No.jpg.
- Paginas: Para contener la pagina de lista de empleados.
Crear el Archivo de Hoja de Estilo (CSS)
Seleccionar la carpeta "Estilos" y agregar un archivo de hoja de estilos con el nombre de: "ACME.css" y modificar el código como sigue:
Escribir el siguiente código C# en la página:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
using Northwind.Librerias.ReglasNegocio; //brEmpleado
using System.Reflection; //PropertyInfo
public partial class Paginas_ListaEmpleados : System.Web.UI.Page
{
private List<beEmpleado> lbeEmpleado;
private int registrosPagina = 6;
private int indicePaginaActual;
private int indiceUltimaPagina;
protected void Page_Load(object sender, EventArgs e)
{
txtPosicion.Attributes.Add("style", "text-align:center");
if (!Page.IsPostBack)
{
brEmpleado obrEmpleado = new brEmpleado();
lbeEmpleado = obrEmpleado.listar();
Session["Empleados"] = lbeEmpleado;
Session["Todo"] = lbeEmpleado;
calcularPaginacion();
enlazarDataList();
cargarListaCampos();
}
else
{
indicePaginaActual = (int)ViewState["indicePaginaActual"];
indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
}
crearEnlacesPaginas();
}
private void calcularPaginacion()
{
indiceUltimaPagina = (lbeEmpleado.Count / registrosPagina);
if (lbeEmpleado.Count % registrosPagina == 0)
indiceUltimaPagina--;
ViewState["indicePaginaActual"] = indicePaginaActual;
ViewState["indiceUltimaPagina"] = indiceUltimaPagina;
}
private void cargarListaCampos()
{
ddlCriterio.Items.Add(new ListItem("Todo", ""));
PropertyInfo[] propiedades = lbeEmpleado[0].
GetType().GetProperties();
foreach (PropertyInfo propiedad in propiedades)
{
ddlCampo.Items.Add(new ListItem
(propiedad.Name, propiedad.Name));
ddlCriterio.Items.Add(new ListItem
(propiedad.Name, propiedad.Name));
}
}
private void crearEnlacesPaginas()
{
celdaPaginas.Controls.Clear();
LinkButton lbn;
for (int i = 0; i <= indiceUltimaPagina; i++)
{
lbn = new LinkButton();
lbn.Text = (i + 1).ToString();
lbn.Click += new EventHandler(paginar);
celdaPaginas.Controls.Add(lbn);
celdaPaginas.Controls.Add(new LiteralControl(" "));
}
}
private void paginar(object sender, EventArgs e)
{
LinkButton lbn = (LinkButton)sender;
indicePaginaActual = int.Parse(lbn.Text) - 1;
ViewState["indicePaginaActual"] = indicePaginaActual;
enlazarDataList();
}
private void enlazarDataList()
{
indicePaginaActual = (int)ViewState["indicePaginaActual"];
indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
lbeEmpleado = (List<beEmpleado>)Session["Empleados"];
List<beEmpleado> lbeFiltro = new List<beEmpleado>();
int inicio = indicePaginaActual * registrosPagina;
int fin = (indicePaginaActual * registrosPagina) + registrosPagina;
for (int i = inicio; i < fin; i++)
{
if (i < lbeEmpleado.Count) lbeFiltro.Add(lbeEmpleado[i]);
else break;
}
dlsEmpleado.DataSource = lbeFiltro;
dlsEmpleado.DataBind();
lblRegistros.Text = lbeEmpleado.Count.ToString();
txtPosicion.Text = String.Format("{0} de {1}", indicePaginaActual + 1,
indiceUltimaPagina + 1);
}
protected void ordenarCampo(object sender, EventArgs e)
{
string campo = ddlCampo.SelectedValue;
int orden = int.Parse(ddlOrden.SelectedValue);
lbeEmpleado = (List<beEmpleado>)Session["Empleados"];
if (orden.Equals(0)) lbeEmpleado = lbeEmpleado.OrderBy
(x => x.GetType().GetProperty(campo).GetValue(x, null)).ToList<beEmpleado>();
else lbeEmpleado = lbeEmpleado.OrderByDescending
(x => x.GetType().GetProperty(campo).GetValue(x, null)).ToList<beEmpleado>();
Session["Empleados"] = lbeEmpleado;
enlazarDataList();
}
protected void filtrarCriterio(object sender, EventArgs e)
{
string campo = ddlCriterio.SelectedValue;
lbeEmpleado = (List<beEmpleado>)Session["Todo"];
if (!campo.Equals(""))
{
string tipo = lbeEmpleado[0].GetType().GetProperty(campo).
PropertyType.ToString().ToLower();
if (tipo.Contains("datetime"))
{
string[] fechaNac = txtDato.Text.Split('-');
txtDato.Text = fechaNac[2] + "/" + fechaNac[1] + "/" + fechaNac[0];
}
lbeEmpleado = lbeEmpleado.FindAll(x => x.GetType().GetProperty(campo).
GetValue(x, null).ToString().ToLower().Contains(txtDato.Text.ToLower()));
}
celdaBotones.Visible = (lbeEmpleado.Count > 0);
Session["Empleados"] = lbeEmpleado;
indicePaginaActual = 0;
ViewState["indicePaginaActual"] = indicePaginaActual;
calcularPaginacion();
enlazarDataList();
crearEnlacesPaginas();
}
protected void btnPrimero_Click(object sender, EventArgs e)
{
indicePaginaActual = 0;
ViewState["indicePaginaActual"] = indicePaginaActual;
enlazarDataList();
}
protected void btnAnterior_Click(object sender, EventArgs e)
{
indicePaginaActual = (int)ViewState["indicePaginaActual"];
if (indicePaginaActual > 0) indicePaginaActual--;
ViewState["indicePaginaActual"] = indicePaginaActual;
enlazarDataList();
}
protected void btnSiguiente_Click(object sender, EventArgs e)
{
indicePaginaActual = (int)ViewState["indicePaginaActual"];
indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
if (indicePaginaActual < indiceUltimaPagina) indicePaginaActual++;
ViewState["indicePaginaActual"] = indicePaginaActual;
enlazarDataList();
}
protected void btnUltimo_Click(object sender, EventArgs e)
{
indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
indicePaginaActual = indiceUltimaPagina;
ViewState["indicePaginaActual"] = indicePaginaActual;
enlazarDataList();
}
protected void cambiarControlBusqueda(object sender, EventArgs e)
{
string campo = ddlCriterio.SelectedValue;
txtDato.Text = "";
if (campo.Equals("")) txtDato.TextMode = TextBoxMode.SingleLine;
else
{
lbeEmpleado = (List<beEmpleado>)Session["Empleados"];
string tipo = lbeEmpleado[0].GetType().GetProperty(campo).
PropertyType.ToString().ToLower();
if (tipo.Contains("int")) txtDato.TextMode = TextBoxMode.Number;
else
{
if (tipo.Contains("datetime")) txtDato.TextMode = TextBoxMode.Date;
else txtDato.TextMode = TextBoxMode.SingleLine;
}
}
enlazarDataList();
}
}
Nota: Por defecto los registrosPorPagina está configurado a 6 y usamos Reflection para cargar dinamicamente los combos con los nombres de las propiedades del objeto empleado.
Modificar el Archivo Web.Config para especificar la cadena de conexión a Northwind
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="conNW" providerName="SQLServer" connectionString="uid=UsuarioNW;pwd=123456;
data source=DSOFT\Sqlexpress; database=Northwind"/>
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
</configuration>
Probar la Pagina Web
Guardar el Sitio Web, clic derecho a la Pagina "ListaEmpleados.aspx" y seleccionar "Ver en el explorador".
Probar ir a cualquier pagina usando los Links con los números de paginas o con los botones, por ejemplo si estamos en la ultima ya no podemos avanzar a la siguiente o si estamos en la primera ya no podemos retroceder.
Seleccionar un criterio del combo "Ordenar Por", luego seleccionar el "Tipo de Orden" (ascendente o descendente) y clic al botón "Ordenar", ver como los registros se ordenan por el campo seleccionado.
Seleccionar un criterio del combo "Filtrar Por", luego ingresar un dato en "Dato Filtrar" y clic al botón "Filtrar", ver como solo aparecen los registros que cumplen con el criterio, se muestra la cantidad de registros encontrados y como varia los números de paginas.
Comentario Final
En esta demostración hemos visto como podemos paginar, ordenar y filtrar usando el control DataList y sin usar ViewState para dicho control para minimizar el HTML enviado al navegador. Mas bien hemos usado el ViewState (y no Session) para almacenar y recuperar el "indicePaginaActual" y el "indiceUltimaPagina" ya que al hacer PostBack se pierden los valores de las variables.
Descarga:
Demo14_Paginar_Ordenar_Filtrar_DataList
Requerimientos
Se desea crear una Aplicación Web que permita listar los datos de los empleados que cumpla con lo siguiente:
- Presente en forma de ficha la información del código, apellido, nombre y fecha de nacimiento del empleado.
- Muestre en la ficha la foto del empleado la cual se encuentra en un carpeta "Empleados" donde el nombre del archivo esta compuesto por el código del empleado y la extensión jpg. Para los archivos que no se encuentren se usará el archivo No.jpg.
- Las fichas deben tener fondo gris claro, pero al pasar el mouse el estilo de la ficha cambiara a fondo amarillo.
- La información debe estar paginada (por defecto mostrar 6 registros de empleados), mediante botones de desplazamiento y enlaces con números de paginas.
- Se debe permitir ordenar los registros por cualquier campo en forma ascendente y descendente.
- Se debe permitir filtrar los registros por cualquier campo ingresando el dato buscado.
Solución
Usaremos el control DataList con Plantilla de Datos para poder presentar en forma de ficha la información del empleado y mostrarla en varias columnas. Ademas agregaremos botones y enlaces para paginar, combos para seleccionar los criterios de ordenación y filtro de registros.
Nota: En este caso si podemos deshabilitar el ViewState del DataList ya que no hay ningun control dentro de la plantilla que haga PostBack, es decir enviaremos el minimo HTML al navegador en el cliente.
Crear el Procedimiento Almacenado en la Base de Datos de SQL Server
Usaremos la tabla Empleados (Employees) de Northwind:
Create Procedure [dbo].[uspEmployeesListar]
As
Select EmployeeID,LastName,FirstName,
IsNull(BirthDate,'1/1/1900') As BirthDate
From Employees Order By 1
Crear una Librería de Clases con las Entidades del Negocio
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.EntidadesNegocio" y modificar el código de la clase como sigue:
using System;
namespace Northwind.Librerias.EntidadesNegocio
{
public class beEmpleado
{
public int IdEmpleado { get; set; }
public string Apellido { get; set; }
public string Nombre { get; set; }
public string NombreCompleto
{
get
{
return (String.Format("{0} {1}",Nombre,Apellido));
}
}
public DateTime FechaNacimiento { get; set; }
}
}
Crear una Librería de Acceso a Datos
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.AccesoDatos" y modificar el código de la clase como sigue:
using System;
using System.Data; //CommandType
using System.Data.SqlClient; //SqlConnection, SqlCommand, SqlDataReader
using System.Collections.Generic; //List
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
namespace Northwind.Librerias.AccesoDatos
{
public class daEmpleado
{
public List<beEmpleado> listar(SqlConnection con)
{
List<beEmpleado> lbeEmpleado = null;
SqlCommand cmd = new SqlCommand("uspEmployeesListar", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader drd = cmd.ExecuteReader(CommandBehavior.SingleResult);
if (drd != null)
{
lbeEmpleado = new List<beEmpleado>();
int posIdEmpleado = drd.GetOrdinal("EmployeeID");
int posApellido = drd.GetOrdinal("LastName");
int posNombre = drd.GetOrdinal("FirstName");
int posFechaNacimiento = drd.GetOrdinal("BirthDate");
beEmpleado obeEmpleado;
while (drd.Read())
{
obeEmpleado = new beEmpleado();
obeEmpleado.IdEmpleado = drd.GetInt32(posIdEmpleado);
obeEmpleado.Apellido = drd.GetString(posApellido);
obeEmpleado.Nombre = drd.GetString(posNombre);
obeEmpleado.FechaNacimiento = drd.GetDateTime(posFechaNacimiento);
lbeEmpleado.Add(obeEmpleado);
}
drd.Close();
}
return (lbeEmpleado);
}
}
}
Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio.
Crear una Librería de Reglas del Negocio
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.ReglasNegocio" y modificar el código de la clase como sigue:
using System;
using System.Configuration; //ConfigurationManager
namespace Northwind.Librerias.ReglasNegocio
{
public class brGeneral
{
//Propiedad
public string Conexion { get; set; }
//Constructor
public brGeneral()
{
Conexion = ConfigurationManager.ConnectionStrings["conNW"].ConnectionString;
}
}
}
Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio, a la Librería de Acceso a Datos y a System.Configuration.
Agregar otra clase llamada: "brEmpleado" y escribir el siguiente código:
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Northwind.Librerias.EntidadesNegocio;
using Northwind.Librerias.AccesoDatos;
namespace Northwind.Librerias.ReglasNegocio
{
public class brEmpleado:brGeneral //Herencia
{
public List<beEmpleado> listar()
{
List<beEmpleado> lbeEmpleado = null;
using (SqlConnection con = new SqlConnection(Conexion))
{
try
{
con.Open();
daEmpleado odaEmpleado = new daEmpleado();
lbeEmpleado = odaEmpleado.listar(con);
}
catch (SqlException ex)
{
//Capturar el error y grabar un Log
}
} //con.Close(); con.Dispose(); con = null;
return (lbeEmpleado);
}
}
}
Nota: La clase "brEmpleado" hereda de la clase "brGeneral" la cadena de conexión para no pasarla como parámetro en cada método de la clase o en el constructor de cada clase se hace una sola vez.
Crear una Librería de Código de Usuario para Web
Crear un proyecto de tipo Librería de Clases en C# llamado: "General.Librerias.CodigoUsuarioWeb" y modificar el código de la clase como sigue:
using System;
using System.Collections.Generic;
using System.IO; //File
using System.Web; //HttpContext
namespace General.Librerias.CodigoUsuarioWeb
{
public class Imagen
{
public static string obtenerUrl(int id, string carpeta)
{
string archivo = HttpContext.Current.Server.MapPath
(String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id));
string url = String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id);
if (!File.Exists(archivo)) url = String.Format("../Imagenes/{0}/No.jpg", carpeta);
return (url);
}
}
}
Nota: Como esta librería va a ser usada por paginas web hay que hacer referencia a: "System.Web"
Crear la Aplicación Web en ASP .NET Web Form
Crear un "Nuevo Sitio web vacío de ASP .NET" en C# llamado "Demo14" y crear las siguientes carpetas:
- Estilos: Para el archivo de hoja de estilo (CSS).
- Imagenes. Dentro crear otra carpeta llamada "Empleados" y adjuntar los archivos con las fotos de los empleados: 1.jpg, 2.jpg, 3.jpg, ... y No.jpg.
- Paginas: Para contener la pagina de lista de empleados.
Crear el Archivo de Hoja de Estilo (CSS)
Seleccionar la carpeta "Estilos" y agregar un archivo de hoja de estilos con el nombre de: "ACME.css" y modificar el código como sigue:
body {
background-color:aqua;
}
.Titulo {
background-color:black;
color:white;
text-transform:uppercase;
font-size:xx-large;
font-weight:bold;
}
.Subtitulo {
background-color:white;
color:blue;
text-transform:capitalize;
font-size:x-large;
font-weight:bold;
}
.MarcarTabla {
background-color: lightgray;
cursor:default;
border:solid;
border-color:lightgray;
}
.MarcarTabla:hover {
background-color: yellow;
cursor:pointer;
border:solid;
border-color:black;
}
Crear la Pagina ASP .NET como un Formulario Web Form
Seleccionar la carpeta "Paginas" y agregar un Formulario Web Form llamado: "ListaEmpleados.aspx", para empezar a diseñar la pagina hay que hacer referencia a las Librerías de Negocio (que copia todas sus dependencias) y la Librería de Código de Usuario Web.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ListaEmpleados.aspx.cs" Inherits="Paginas_ListaEmpleados" %>
<%@ Import Namespace="Northwind.Librerias.EntidadesNegocio" %>
<%@ Import Namespace="General.Librerias.CodigoUsuarioWeb" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<link href="../Estilos/ACME.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>
<table style="width:100%">
<tr>
<td class="Titulo" colspan="5">Paginar, Ordenar y Filtrar en el DataList</td>
</tr>
<tr>
<td class="Subtitulo" colspan="5">Lista de Empleados</td>
</tr>
<tr>
<td style="width:10%">Ordenar Por: </td>
<td style="width:20%">
<asp:DropDownList ID="ddlCampo" runat="server" />
</td>
<td style="width:10%">Tipo Orden: </td>
<td style="width:20%">
<asp:DropDownList ID="ddlOrden" runat="server">
<asp:ListItem Value="0">Ascendente</asp:ListItem>
<asp:ListItem Value="1">Descendente</asp:ListItem>
</asp:DropDownList>
</td>
<td style="width:40%">
<asp:Button ID="btnOrdenar" Text="Ordenar"
OnClick="ordenarCampo" runat="server"/>
</td>
</tr>
<tr>
<td style="width:10%">Filtrar Por: </td>
<td style="width:20%">
<asp:DropDownList ID="ddlCriterio" runat="server" AutoPostBack="True"
OnSelectedIndexChanged="cambiarControlBusqueda" />
</td>
<td style="width:10%">Dato Filtrar: </td>
<td style="width:20%">
<asp:TextBox ID="txtDato" Width="130" runat="server" />
</td>
<td style="width:40%">
<asp:Button ID="btnFiltrar" Text="Filtrar" OnClick="filtrarCriterio" runat="server"/>
</td>
</tr>
<tr>
<td colspan="5" class="Subtitulo">Registros encontrados:
<asp:Label ID="lblRegistros" Text="0" runat="server"/>
</td>
</tr>
<tr>
<td colspan="5">
<asp:DataList ID="dlsEmpleado" runat="server" EnableViewState="False"
RepeatColumns="3" CellPadding="15" CellSpacing="15"
RepeatDirection="Horizontal">
RepeatDirection="Horizontal">
<ItemTemplate>
<table class="MarcarTabla">
<tr>
<td>
<table>
<tr>
<td style="width:80px">Código :</td>
<td style="width:100px">
<%#((beEmpleado)Container.DataItem).IdEmpleado%>
</td>
</tr>
<tr>
<td style="width:80px">Apellido :</td>
<td style="width:100px">
<%#((beEmpleado)Container.DataItem).Apellido%>
</td>
</tr>
<tr>
<td style="width:80px">Nombre :</td>
<td style="width:100px">
<%#((beEmpleado)Container.DataItem).Nombre%>
</td>
</tr>
<tr>
<td style="width:80px">Fecha Nac :</td>
<td style="width:100px">
<%#((beEmpleado)Container.DataItem).FechaNacimiento.
ToShortDateString()%>
</td>
</tr>
</table>
</td>
<td>
<img src='<%#Imagen.obtenerUrl(((beEmpleado)Container.DataItem).
IdEmpleado,"Empleados")%>' width="120" height="80" alt="Foto"
title="<%#((beEmpleado)Container.DataItem).NombreCompleto%>"/>
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
</td>
</tr>
<tr>
<td id="celdaBotones" style="text-align:center" colspan="5" runat="server">
<asp:Button ID="btnPrimero" Text="<<" Width="50"
runat="server" OnClick="btnPrimero_Click" />
<asp:Button ID="btnAnterior" Text="<" Width="50"
runat="server" OnClick="btnAnterior_Click" />
<asp:TextBox ID="txtPosicion" Width="100" ReadOnly="true" runat="server" />
<asp:Button ID="btnSiguiente" Text=">" Width="50"
runat="server" OnClick="btnSiguiente_Click" />
<asp:Button ID="btnUltimo" Text=">>" Width="50"
runat="server" OnClick="btnUltimo_Click" />
</td>
</tr>
<tr>
<td id="celdaPaginas" style="text-align:center" colspan="5" runat="server">
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
El diseño de la pagina se mostrará como en la siguiente figura:
Escribir el siguiente código C# en la página:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
using Northwind.Librerias.ReglasNegocio; //brEmpleado
using System.Reflection; //PropertyInfo
public partial class Paginas_ListaEmpleados : System.Web.UI.Page
{
private List<beEmpleado> lbeEmpleado;
private int registrosPagina = 6;
private int indicePaginaActual;
private int indiceUltimaPagina;
protected void Page_Load(object sender, EventArgs e)
{
txtPosicion.Attributes.Add("style", "text-align:center");
if (!Page.IsPostBack)
{
brEmpleado obrEmpleado = new brEmpleado();
lbeEmpleado = obrEmpleado.listar();
Session["Empleados"] = lbeEmpleado;
Session["Todo"] = lbeEmpleado;
calcularPaginacion();
enlazarDataList();
cargarListaCampos();
}
else
{
indicePaginaActual = (int)ViewState["indicePaginaActual"];
indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
}
crearEnlacesPaginas();
}
private void calcularPaginacion()
{
indiceUltimaPagina = (lbeEmpleado.Count / registrosPagina);
if (lbeEmpleado.Count % registrosPagina == 0)
indiceUltimaPagina--;
ViewState["indicePaginaActual"] = indicePaginaActual;
ViewState["indiceUltimaPagina"] = indiceUltimaPagina;
}
private void cargarListaCampos()
{
ddlCriterio.Items.Add(new ListItem("Todo", ""));
PropertyInfo[] propiedades = lbeEmpleado[0].
GetType().GetProperties();
foreach (PropertyInfo propiedad in propiedades)
{
ddlCampo.Items.Add(new ListItem
(propiedad.Name, propiedad.Name));
ddlCriterio.Items.Add(new ListItem
(propiedad.Name, propiedad.Name));
}
}
private void crearEnlacesPaginas()
{
celdaPaginas.Controls.Clear();
LinkButton lbn;
for (int i = 0; i <= indiceUltimaPagina; i++)
{
lbn = new LinkButton();
lbn.Text = (i + 1).ToString();
lbn.Click += new EventHandler(paginar);
celdaPaginas.Controls.Add(lbn);
celdaPaginas.Controls.Add(new LiteralControl(" "));
}
}
private void paginar(object sender, EventArgs e)
{
LinkButton lbn = (LinkButton)sender;
indicePaginaActual = int.Parse(lbn.Text) - 1;
ViewState["indicePaginaActual"] = indicePaginaActual;
enlazarDataList();
}
private void enlazarDataList()
{
indicePaginaActual = (int)ViewState["indicePaginaActual"];
indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
lbeEmpleado = (List<beEmpleado>)Session["Empleados"];
List<beEmpleado> lbeFiltro = new List<beEmpleado>();
int inicio = indicePaginaActual * registrosPagina;
int fin = (indicePaginaActual * registrosPagina) + registrosPagina;
for (int i = inicio; i < fin; i++)
{
if (i < lbeEmpleado.Count) lbeFiltro.Add(lbeEmpleado[i]);
else break;
}
dlsEmpleado.DataSource = lbeFiltro;
dlsEmpleado.DataBind();
lblRegistros.Text = lbeEmpleado.Count.ToString();
txtPosicion.Text = String.Format("{0} de {1}", indicePaginaActual + 1,
indiceUltimaPagina + 1);
}
protected void ordenarCampo(object sender, EventArgs e)
{
string campo = ddlCampo.SelectedValue;
int orden = int.Parse(ddlOrden.SelectedValue);
lbeEmpleado = (List<beEmpleado>)Session["Empleados"];
if (orden.Equals(0)) lbeEmpleado = lbeEmpleado.OrderBy
(x => x.GetType().GetProperty(campo).GetValue(x, null)).ToList<beEmpleado>();
else lbeEmpleado = lbeEmpleado.OrderByDescending
(x => x.GetType().GetProperty(campo).GetValue(x, null)).ToList<beEmpleado>();
Session["Empleados"] = lbeEmpleado;
enlazarDataList();
}
protected void filtrarCriterio(object sender, EventArgs e)
{
string campo = ddlCriterio.SelectedValue;
lbeEmpleado = (List<beEmpleado>)Session["Todo"];
if (!campo.Equals(""))
{
string tipo = lbeEmpleado[0].GetType().GetProperty(campo).
PropertyType.ToString().ToLower();
if (tipo.Contains("datetime"))
{
string[] fechaNac = txtDato.Text.Split('-');
txtDato.Text = fechaNac[2] + "/" + fechaNac[1] + "/" + fechaNac[0];
}
lbeEmpleado = lbeEmpleado.FindAll(x => x.GetType().GetProperty(campo).
GetValue(x, null).ToString().ToLower().Contains(txtDato.Text.ToLower()));
}
celdaBotones.Visible = (lbeEmpleado.Count > 0);
Session["Empleados"] = lbeEmpleado;
indicePaginaActual = 0;
ViewState["indicePaginaActual"] = indicePaginaActual;
calcularPaginacion();
enlazarDataList();
crearEnlacesPaginas();
}
protected void btnPrimero_Click(object sender, EventArgs e)
{
indicePaginaActual = 0;
ViewState["indicePaginaActual"] = indicePaginaActual;
enlazarDataList();
}
protected void btnAnterior_Click(object sender, EventArgs e)
{
indicePaginaActual = (int)ViewState["indicePaginaActual"];
if (indicePaginaActual > 0) indicePaginaActual--;
ViewState["indicePaginaActual"] = indicePaginaActual;
enlazarDataList();
}
protected void btnSiguiente_Click(object sender, EventArgs e)
{
indicePaginaActual = (int)ViewState["indicePaginaActual"];
indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
if (indicePaginaActual < indiceUltimaPagina) indicePaginaActual++;
ViewState["indicePaginaActual"] = indicePaginaActual;
enlazarDataList();
}
protected void btnUltimo_Click(object sender, EventArgs e)
{
indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
indicePaginaActual = indiceUltimaPagina;
ViewState["indicePaginaActual"] = indicePaginaActual;
enlazarDataList();
}
protected void cambiarControlBusqueda(object sender, EventArgs e)
{
string campo = ddlCriterio.SelectedValue;
txtDato.Text = "";
if (campo.Equals("")) txtDato.TextMode = TextBoxMode.SingleLine;
else
{
lbeEmpleado = (List<beEmpleado>)Session["Empleados"];
string tipo = lbeEmpleado[0].GetType().GetProperty(campo).
PropertyType.ToString().ToLower();
if (tipo.Contains("int")) txtDato.TextMode = TextBoxMode.Number;
else
{
if (tipo.Contains("datetime")) txtDato.TextMode = TextBoxMode.Date;
else txtDato.TextMode = TextBoxMode.SingleLine;
}
}
enlazarDataList();
}
}
Nota: Por defecto los registrosPorPagina está configurado a 6 y usamos Reflection para cargar dinamicamente los combos con los nombres de las propiedades del objeto empleado.
Modificar el Archivo Web.Config para especificar la cadena de conexión a Northwind
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="conNW" providerName="SQLServer" connectionString="uid=UsuarioNW;pwd=123456;
data source=DSOFT\Sqlexpress; database=Northwind"/>
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
</configuration>
Probar la Pagina Web
Guardar el Sitio Web, clic derecho a la Pagina "ListaEmpleados.aspx" y seleccionar "Ver en el explorador".
Probar ir a cualquier pagina usando los Links con los números de paginas o con los botones, por ejemplo si estamos en la ultima ya no podemos avanzar a la siguiente o si estamos en la primera ya no podemos retroceder.
Seleccionar un criterio del combo "Ordenar Por", luego seleccionar el "Tipo de Orden" (ascendente o descendente) y clic al botón "Ordenar", ver como los registros se ordenan por el campo seleccionado.
Seleccionar un criterio del combo "Filtrar Por", luego ingresar un dato en "Dato Filtrar" y clic al botón "Filtrar", ver como solo aparecen los registros que cumplen con el criterio, se muestra la cantidad de registros encontrados y como varia los números de paginas.
Comentario Final
En esta demostración hemos visto como podemos paginar, ordenar y filtrar usando el control DataList y sin usar ViewState para dicho control para minimizar el HTML enviado al navegador. Mas bien hemos usado el ViewState (y no Session) para almacenar y recuperar el "indicePaginaActual" y el "indiceUltimaPagina" ya que al hacer PostBack se pierden los valores de las variables.
Descarga:
Demo14_Paginar_Ordenar_Filtrar_DataList
Etiquetas:
C#,
CSS,
Data Templates,
DataList,
Demos,
Filtrar,
Lduenas,
Librerías,
LinkButton,
Listas de Objetos,
Ordenar,
Paginar,
Plantilla de Datos,
Reflection,
ViewState,
Web Control,
WebForms
sábado, 26 de julio de 2014
El Demo del Día: Plantilla de Datos en el Control Web DataList
Requerimientos
Se desea crear una Aplicación Web que permita listar los datos de los empleados que cumpla con lo siguiente:
- Presente en forma de ficha la información del código, apellido, nombre y fecha de nacimiento del empleado.
- Muestre en la ficha la foto del empleado la cual se encuentra en un carpeta "Empleados" donde el nombre del archivo esta compuesto por el código del empleado y la extensión jpg. Para los archivos que no se encuentren se usará el archivo No.jpg.
- La información debe aparecer solo en una pagina en forma de cuadro con borde distribuida en columnas.
- Las fichas deben tener fondo gris claro, pero al pasar el mouse el estilo de la ficha cambiara a fondo amarillo.
Nota: El principal requerimiento es que la pagina sea rápida y que arroje la menor cantidad de HTML en el cliente. Además el Usuario No quiere Paginado ya que no son demasiados los registros a mostrar.
Solución
Usaremos el control DataList y le quitaremos el ViewState (EnableViewState=false) para reducir el HTML arrojado al cliente y para mejorar la apariencia de la pagina usaremos estilos para las fichas de datos.
Ademas usando Plantilla de Datos en el Control DataList podemos presentar en forma de ficha la información del empleado y mostrarla en varias columnas.
Crear el Procedimiento Almacenado en la Base de Datos de SQL Server
Usaremos la tabla Empleados (Employees) de Northwind:
Create Procedure [dbo].[uspEmployeesListar]
As
Select EmployeeID,LastName,FirstName,
IsNull(BirthDate,'1/1/1900') As BirthDate
From Employees Order By 1
Crear una Librería de Clases con las Entidades del Negocio
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.EntidadesNegocio" y modificar el código de la clase como sigue:
using System;
namespace Northwind.Librerias.EntidadesNegocio
{
public class beEmpleado
{
public int IdEmpleado { get; set; }
public string Apellido { get; set; }
public string Nombre { get; set; }
public string NombreCompleto
{
get
{
return (String.Format("{0} {1}",Nombre,Apellido));
}
}
public DateTime FechaNacimiento { get; set; }
}
}
Crear una Librería de Acceso a Datos
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.AccesoDatos" y modificar el código de la clase como sigue:
using System;
using System.Data; //CommandType
using System.Data.SqlClient; //SqlConnection, SqlCommand, SqlDataReader
using System.Collections.Generic; //List
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
namespace Northwind.Librerias.AccesoDatos
{
public class daEmpleado
{
public List<beEmpleado> listar(SqlConnection con)
{
List<beEmpleado> lbeEmpleado = null;
SqlCommand cmd = new SqlCommand("uspEmployeesListar", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader drd = cmd.ExecuteReader(CommandBehavior.SingleResult);
if (drd != null)
{
lbeEmpleado = new List<beEmpleado>();
int posIdEmpleado = drd.GetOrdinal("EmployeeID");
int posApellido = drd.GetOrdinal("LastName");
int posNombre = drd.GetOrdinal("FirstName");
int posFechaNacimiento = drd.GetOrdinal("BirthDate");
beEmpleado obeEmpleado;
while (drd.Read())
{
obeEmpleado = new beEmpleado();
obeEmpleado.IdEmpleado = drd.GetInt32(posIdEmpleado);
obeEmpleado.Apellido = drd.GetString(posApellido);
obeEmpleado.Nombre = drd.GetString(posNombre);
obeEmpleado.FechaNacimiento = drd.GetDateTime(posFechaNacimiento);
lbeEmpleado.Add(obeEmpleado);
}
drd.Close();
}
return (lbeEmpleado);
}
}
}
Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio.
Crear una Librería de Reglas del Negocio
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.ReglasNegocio" y modificar el código de la clase como sigue:
using System;
using System.Configuration; //ConfigurationManager
namespace Northwind.Librerias.ReglasNegocio
{
public class brGeneral
{
//Propiedad
public string Conexion { get; set; }
//Constructor
public brGeneral()
{
Conexion = ConfigurationManager.ConnectionStrings["conNW"].ConnectionString;
}
}
}
Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio, a la Librería de Acceso a Datos y a System.Configuration.
Agregar otra clase llamada: "brEmpleado" y escribir el siguiente código:
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Northwind.Librerias.EntidadesNegocio;
using Northwind.Librerias.AccesoDatos;
namespace Northwind.Librerias.ReglasNegocio
{
public class brEmpleado:brGeneral //Herencia
{
public List<beEmpleado> listar()
{
List<beEmpleado> lbeEmpleado = null;
using (SqlConnection con = new SqlConnection(Conexion))
{
try
{
con.Open();
daEmpleado odaEmpleado = new daEmpleado();
lbeEmpleado = odaEmpleado.listar(con);
}
catch (SqlException ex)
{
//Capturar el error y grabar un Log
}
} //con.Close(); con.Dispose(); con = null;
return (lbeEmpleado);
}
}
}
Nota: La clase "brEmpleado" hereda de la clase "brGeneral" la cadena de conexión para no pasarla como parámetro en cada método de la clase o en el constructor de cada clase se hace una sola vez.
Crear una Librería de Código de Usuario para Web
Crear un proyecto de tipo Librería de Clases en C# llamado: "General.Librerias.CodigoUsuarioWeb" y modificar el código de la clase como sigue:
using System;
using System.Collections.Generic;
using System.IO; //File
using System.Web; //HttpContext
namespace General.Librerias.CodigoUsuarioWeb
{
public class Imagen
{
public static string obtenerUrl(int id, string carpeta)
{
string archivo = HttpContext.Current.Server.MapPath
(String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id));
string url = String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id);
if (!File.Exists(archivo)) url = String.Format("../Imagenes/{0}/No.jpg", carpeta);
return (url);
}
}
}
Nota: Como esta librería va a ser usada por paginas web hay que hacer referencia a: "System.Web"
Crear la Aplicación Web en ASP .NET Web Form
Crear un "Nuevo Sitio web vacío de ASP .NET" en C# llamado "Demo12" y crear las siguientes carpetas:
- Estilos: Para el archivo de hoja de estilo (CSS).
- Imagenes. Dentro crear otra carpeta llamada "Empleados" y adjuntar los archivos con las fotos de los empleados: 1.jpg, 2.jpg, 3.jpg, ... y No.jpg.
- Paginas: Para contener la pagina de lista de empleados.
Crear el Archivo de Hoja de Estilo (CSS)
Seleccionar la carpeta "Estilos" y agregar un archivo de hoja de estilos con el nombre de: "ACME.css" y modificar el código como sigue:
Se desea crear una Aplicación Web que permita listar los datos de los empleados que cumpla con lo siguiente:
- Presente en forma de ficha la información del código, apellido, nombre y fecha de nacimiento del empleado.
- Muestre en la ficha la foto del empleado la cual se encuentra en un carpeta "Empleados" donde el nombre del archivo esta compuesto por el código del empleado y la extensión jpg. Para los archivos que no se encuentren se usará el archivo No.jpg.
- La información debe aparecer solo en una pagina en forma de cuadro con borde distribuida en columnas.
- Las fichas deben tener fondo gris claro, pero al pasar el mouse el estilo de la ficha cambiara a fondo amarillo.
Nota: El principal requerimiento es que la pagina sea rápida y que arroje la menor cantidad de HTML en el cliente. Además el Usuario No quiere Paginado ya que no son demasiados los registros a mostrar.
Solución
Usaremos el control DataList y le quitaremos el ViewState (EnableViewState=false) para reducir el HTML arrojado al cliente y para mejorar la apariencia de la pagina usaremos estilos para las fichas de datos.
Ademas usando Plantilla de Datos en el Control DataList podemos presentar en forma de ficha la información del empleado y mostrarla en varias columnas.
Crear el Procedimiento Almacenado en la Base de Datos de SQL Server
Usaremos la tabla Empleados (Employees) de Northwind:
Create Procedure [dbo].[uspEmployeesListar]
As
Select EmployeeID,LastName,FirstName,
IsNull(BirthDate,'1/1/1900') As BirthDate
From Employees Order By 1
Crear una Librería de Clases con las Entidades del Negocio
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.EntidadesNegocio" y modificar el código de la clase como sigue:
using System;
namespace Northwind.Librerias.EntidadesNegocio
{
public class beEmpleado
{
public int IdEmpleado { get; set; }
public string Apellido { get; set; }
public string Nombre { get; set; }
public string NombreCompleto
{
get
{
return (String.Format("{0} {1}",Nombre,Apellido));
}
}
public DateTime FechaNacimiento { get; set; }
}
}
Crear una Librería de Acceso a Datos
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.AccesoDatos" y modificar el código de la clase como sigue:
using System;
using System.Data; //CommandType
using System.Data.SqlClient; //SqlConnection, SqlCommand, SqlDataReader
using System.Collections.Generic; //List
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
namespace Northwind.Librerias.AccesoDatos
{
public class daEmpleado
{
public List<beEmpleado> listar(SqlConnection con)
{
List<beEmpleado> lbeEmpleado = null;
SqlCommand cmd = new SqlCommand("uspEmployeesListar", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader drd = cmd.ExecuteReader(CommandBehavior.SingleResult);
if (drd != null)
{
lbeEmpleado = new List<beEmpleado>();
int posIdEmpleado = drd.GetOrdinal("EmployeeID");
int posApellido = drd.GetOrdinal("LastName");
int posNombre = drd.GetOrdinal("FirstName");
int posFechaNacimiento = drd.GetOrdinal("BirthDate");
beEmpleado obeEmpleado;
while (drd.Read())
{
obeEmpleado = new beEmpleado();
obeEmpleado.IdEmpleado = drd.GetInt32(posIdEmpleado);
obeEmpleado.Apellido = drd.GetString(posApellido);
obeEmpleado.Nombre = drd.GetString(posNombre);
obeEmpleado.FechaNacimiento = drd.GetDateTime(posFechaNacimiento);
lbeEmpleado.Add(obeEmpleado);
}
drd.Close();
}
return (lbeEmpleado);
}
}
}
Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio.
Crear una Librería de Reglas del Negocio
Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.ReglasNegocio" y modificar el código de la clase como sigue:
using System;
using System.Configuration; //ConfigurationManager
namespace Northwind.Librerias.ReglasNegocio
{
public class brGeneral
{
//Propiedad
public string Conexion { get; set; }
//Constructor
public brGeneral()
{
Conexion = ConfigurationManager.ConnectionStrings["conNW"].ConnectionString;
}
}
}
Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio, a la Librería de Acceso a Datos y a System.Configuration.
Agregar otra clase llamada: "brEmpleado" y escribir el siguiente código:
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Northwind.Librerias.EntidadesNegocio;
using Northwind.Librerias.AccesoDatos;
namespace Northwind.Librerias.ReglasNegocio
{
public class brEmpleado:brGeneral //Herencia
{
public List<beEmpleado> listar()
{
List<beEmpleado> lbeEmpleado = null;
using (SqlConnection con = new SqlConnection(Conexion))
{
try
{
con.Open();
daEmpleado odaEmpleado = new daEmpleado();
lbeEmpleado = odaEmpleado.listar(con);
}
catch (SqlException ex)
{
//Capturar el error y grabar un Log
}
} //con.Close(); con.Dispose(); con = null;
return (lbeEmpleado);
}
}
}
Nota: La clase "brEmpleado" hereda de la clase "brGeneral" la cadena de conexión para no pasarla como parámetro en cada método de la clase o en el constructor de cada clase se hace una sola vez.
Crear una Librería de Código de Usuario para Web
Crear un proyecto de tipo Librería de Clases en C# llamado: "General.Librerias.CodigoUsuarioWeb" y modificar el código de la clase como sigue:
using System;
using System.Collections.Generic;
using System.IO; //File
using System.Web; //HttpContext
namespace General.Librerias.CodigoUsuarioWeb
{
public class Imagen
{
public static string obtenerUrl(int id, string carpeta)
{
string archivo = HttpContext.Current.Server.MapPath
(String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id));
string url = String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id);
if (!File.Exists(archivo)) url = String.Format("../Imagenes/{0}/No.jpg", carpeta);
return (url);
}
}
}
Nota: Como esta librería va a ser usada por paginas web hay que hacer referencia a: "System.Web"
Crear la Aplicación Web en ASP .NET Web Form
Crear un "Nuevo Sitio web vacío de ASP .NET" en C# llamado "Demo12" y crear las siguientes carpetas:
- Estilos: Para el archivo de hoja de estilo (CSS).
- Imagenes. Dentro crear otra carpeta llamada "Empleados" y adjuntar los archivos con las fotos de los empleados: 1.jpg, 2.jpg, 3.jpg, ... y No.jpg.
- Paginas: Para contener la pagina de lista de empleados.
Crear el Archivo de Hoja de Estilo (CSS)
Seleccionar la carpeta "Estilos" y agregar un archivo de hoja de estilos con el nombre de: "ACME.css" y modificar el código como sigue:
.Cuadro {
position:absolute;
left:2%;
top:4%;
width:96%;
height:92%;
background-color: gray;
border:solid;
border-color:black;
border-radius:10px;
overflow:scroll;
}
.Titulo {
background-color:black;
color:white;
text-transform:uppercase;
font-size:xx-large;
font-weight:bold;
}
.Subtitulo {
background-color:white;
color:blue;
text-transform:capitalize;
font-size:x-large;
font-weight:bold;
}
.MarcarTabla {
background-color: lightgray;
cursor:default;
border:solid;
border-color:lightgray;
}
.MarcarTabla:hover {
background-color: yellow;
cursor:pointer;
border:solid;
border-color:black;
}
Nota: El estilo "Cuadro" será aplicado al div principal de la pagina y el estilo "MarcarTabla" será aplicado a la tabla que muestra la ficha de cada empleado dentro del DataList.
Crear la Pagina ASP .NET como un Formulario Web Form
Seleccionar la carpeta "Paginas" y agregar un Formulario Web Form llamado: "ListaEmpleados.aspx", para empezar a diseñar la pagina hay que hacer referencia a las Librerías de Negocio (que copia todas sus dependencias) y la Librería de Código de Usuario Web.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ListaEmpleados.aspx.cs" Inherits="Paginas_ListaEmpleados" %>
<%@ Import Namespace="Northwind.Librerias.EntidadesNegocio" %>
<%@ Import Namespace="General.Librerias.CodigoUsuarioWeb" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<link href="../Estilos/ACME.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div class="Cuadro">
<table style="width: 100%">
<tr>
<td class="Titulo">Plantilla y Estilos en el Control DataList</td>
</tr>
<tr>
<td class="Subtitulo">Lista de Empleados</td>
</tr>
<tr>
<td>
<asp:DataList ID="dlsEmpleado" runat="server" EnableViewState="False"
RepeatColumns="3" CellPadding="20" CellSpacing="20"
RepeatDirection="Horizontal">
RepeatDirection="Horizontal">
<ItemTemplate>
<table class="MarcarTabla">
<tr>
<td>
<table>
<tr>
<td style="width:80px">Código :</td>
<td style="width:100px">
<%#((beEmpleado)Container.DataItem).IdEmpleado%>
</td>
</tr>
<tr>
<td style="width:80px">Apellido :</td>
<td style="width:100px">
<%#((beEmpleado)Container.DataItem).Apellido%>
</td>
</tr>
<tr>
<td style="width:80px">Nombre :</td>
<td style="width:100px">
<%#((beEmpleado)Container.DataItem).Nombre%>
</td>
</tr>
<tr>
<td style="width:80px">Fecha Nac :</td>
<td style="width:100px">
<%#((beEmpleado)Container.DataItem).FechaNacimiento.
ToShortDateString()%>
</td>
</tr>
</table>
</td>
<td>
<img src='<%#Imagen.obtenerUrl(((beEmpleado)Container.DataItem).
IdEmpleado,"Empleados")%>' width="120" height="80" alt="Foto"
title="<%#((beEmpleado)Container.DataItem).
NombreCompleto%>"/>
NombreCompleto%>"/>
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
Nota: Se ha configurado las propiedad "RepeatColumns" del Control DataList para distribuir en 3 columnas los datos de los empleados, además la propiedad "RepeatDirection" está en Horizontal y No en Vertical para mostrar la dirección de los registros en filas y no en columnas, de izquierda a derecha y no de arriba hacia abajo. Finalmente, las propiedades CellPadding y CellSpacing permiten dar espaciado a los datos.
El diseño de la pagina se mostrará como en la siguiente figura:
Escribir el siguiente código C# en la página:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
using Northwind.Librerias.ReglasNegocio; //brEmpleado
public partial class Paginas_ListaEmpleados : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
brEmpleado obrEmpleado = new brEmpleado();
List<beEmpleado> lbeEmpleado = obrEmpleado.listar();
dlsEmpleado.DataSource = lbeEmpleado;
dlsEmpleado.DataBind();
}
}
}
Modificar el Archivo Web.Config para especificar la cadena de conexión a Northwind
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="conNW" providerName="SQLServer" connectionString="uid=UsuarioNW;pwd=123456;
data source=DSOFT\Sqlexpress; database=Northwind"/>
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
</configuration>
Probar la Pagina Web
Guardar el Sitio Web, clic derecho a la Pagina "ListaEmpleados.aspx" y seleccionar "Ver en el explorador".
Observar que el contenido aparece sobre un cuadro con borde negro con esquinas redondeadas y los registros de empleados aparecen en pequeñas fichas distribuidas en 3 columnas. El cuadro tiene una barra de desplazamiento (scroll) para ver los demás registros.
Pasar el mouse por cada ficha de empleado y notar como cambia el estilo de la ficha seleccionada debido al estilo "MarcarTabla" aplicado a la tabla que esta dentro del control DataList.
Clic derecho a la página y seleccionar "Ver código fuente de la pagina", notar que el HTML generado desde el servidor es mínimo ya que se le quito el ViewState al control DataList y se uso Hojas de Estilo para reducir el formato en cada tabla.
Comentario Final
En esta demostración usamos el Control DataList para presentar la información en columnas y usando Estilos lo presentamos en una sola pagina en forma de cuadro con una barra de desplazamiento, esta técnica es útil si no son muchas páginas, de lo contrario es mejor Paginar para No enviar demasiado HTML al cliente, lo cual veremos en un siguiente post.
Descarga:
Etiquetas:
ASP .NET,
C#,
CSS,
Data Templates,
DataList,
Demos,
Lduenas,
Librerías,
Plantilla de Datos,
ViewState,
WebForms
Suscribirse a:
Entradas (Atom)




