El control repeater de ASP.NET es un contenedor enlazado a
datos que permite crear listas personalizadas. Este control no posee una
apariencia propia, con lo cual según la plantilla que se realice será como se
mostrará luego en forma de listas. Las listas que son posibles de crear con
este control son: diseño de tabla, delimitada por comas y con formato XML.
El aspecto del repeater así como viene cuando lo
arrastramos a nuestra página es el siguiente:
- <asp:Repeater ID="Repeater1" runat="server">
- </asp:Repeater>
Vamos a hacer un ejemplo con el diseño de tablas para saber
de lo que estamos hablando.
El ejemplo que vamos a realizar será cargar un repeater
con datos de clientes. Para esto
crearemos las clases que nos harán falta junto con sus métodos para cargar el
control.
Los atributos de los clientes serán:
Codigo
NombreFantasia
RazonSocial
Telefono
Direccion
CUIT
DadoDeBaja
Dentro del repeater podremos agregar tanto controles HTML, como ASPX. Estos se repetirán tantas veces como elementos vengan en el datasource del control.
Para poder armar la apariencia que le queremos dar al control, vamos a crear 2 tablas. La primera será para la cabecera del control, que se incluirá dentro de las etiquetas <HeaderTemplate></HeaderTemplate> y la segunda que servirá para mostrar el contenido del Repeter y se incluirá dentro de las etiquetas <ItemTemplate></ItemTemplate>.
La tabla que incluiremos en el HeaderTemplate es la siguiente:
<table>
<tr>
<th id="colEliminar" style="width: 20px;">
</th>
<th style="width: 90px;">
Nombre Fantasia
</th>
<th style="width: 90px;">
Razón Social
</th>
<th style="width: 50px;">
Teléfono
</th>
<th style="width: 150px;">
Dirección
</th>
<th style="width: 70px;">
Cuit
</th>
<th id="check" style="width: 20px;">
Baja
</th>
</tr>
La tabla que incluiremos
en el ItemTemplate es la siguiente:
<tr>
<td>
<asp:ImageButton ID="imgBtnEliminar" runat="server"
CommandName="Eliminar" CommandArgument='<%#Eval("IdCliente")%>' />
</td>
<td>
<%#DataBinder.Eval(Container.DataItem, "NombreFantasia")%>
</td>
<td>
<%#DataBinder.Eval(Container.DataItem,"RazonSocial") %>
</td>
<td>
<%#DataBinder.Eval(Container.DataItem,"Telefono") %>
</td>
<td>
<%#DataBinder.Eval(Container.DataItem,"Direccion") %>
</td>
<td>
<%#DataBinder.Eval(Container.DataItem,"Cuit") %>
</td>
<td align="center">
<asp:CheckBox ID="chkDadoDeBaja" runat="server" Enabled="false" Checked='<%#DataBinder.Eval(Container.DataItem,"DadoDeBaja") %>' />
</td>
</tr>
Notese que no cerré la etiqueta <table> y esto es porque luego agregaremos la etiqueta <FooterTemplate></FooterTemplate> y dentro de esta irá el </table> de esta forma:
<FooterTemplate>
</table>
</FooterTemplate>
De esta forma nuestro
Repeater quedará así:
<asp:Repeater ID="rptClientes" runat="server"
onitemcommand="rptClientes_ItemCommand"
onitemdatabound="rptClientes_ItemDataBound">
<HeaderTemplate>
<table>
<tr>
<th id="colEliminar" style="width: 20px;">
</th>
<th style="width: 90px;">
Nombre Fantasia
</th>
<th style="width: 90px;">
Razón Social
</th>
<th style="width: 50px;">
Teléfono
</th>
<th style="width: 150px;">
Dirección
</th>
<th style="width: 70px;">
Cuit
</th>
<th id="check" style="width: 20px;">
Baja
</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:ImageButton ID="imgBtnEliminar" runat="server"
CommandName="Eliminar" CommandArgument='<%#Eval("IdCliente")%>' />
</td>
<td>
<%#DataBinder.Eval(Container.DataItem, "NombreFantasia")%>
</td>
<td>
<%#DataBinder.Eval(Container.DataItem,"RazonSocial") %>
</td>
<td>
<%#DataBinder.Eval(Container.DataItem,"Telefono") %>
</td>
<td>
<%#DataBinder.Eval(Container.DataItem,"Direccion") %>
</td>
<td>
<%#DataBinder.Eval(Container.DataItem,"Cuit") %>
</td>
<td align="center">
<asp:CheckBox ID="chkDadoDeBaja" runat="server" Enabled="false" Checked='<%#DataBinder.Eval(Container.DataItem,"DadoDeBaja") %>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Ahí quedó listo nuestro
código en la página aspx
Ahora vamos al código c#
en la página RecorrerRepeater.aspx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Negocios;
using System.Data;
namespace RecorrerRepeater
{
public partial class RecorrerRepeater : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnCargarRepeater_Click(object sender, EventArgs e)
{
try
{
Clientes_N unClienteN = new Clientes_N();
DataTable dt = new DataTable();
string sError = "";
sError = unClienteN.Buscar_Todos(ref dt);
if (!string.IsNullOrEmpty(sError)) throw new Exception(sError);
if (dt.Rows.Count > 0)
{
rptClientes.DataSource = dt;
rptClientes.DataBind();
}
}
catch (Exception ex)
{
string msg = "<script type='text/javascript'>alert('" + ex.Message + "');</script>";
Page.ClientScript.RegisterClientScriptBlock(GetType(), "Error", msg);
}
}
}
}
Dentro de nuestro código
se puede ver que hacemos referencia a una clase llamada Clientes_N, esta clase
está definida en otro proyecto al que le dimos el nombre de Negocios para hacer
una separación en capas. Veamos que arriba del código está el using a Negocios.
Vamos a definir la clase
Clientes_N para ver lo que hace:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Datos;
using System.Data;
namespace Negocios
{
public class Clientes_N
{
Clientes_D uncliente_D = new Clientes_D();
public string Buscar_Todos(ref DataTable pS_dt)
{
return uncliente_D.Buscar_Todos(ref pS_dt);
}
}
}
Esta clase como se puede
ver lo que hace es llamar a un método de otra clase llamada Clientes_D de otro
proyecto denominado Datos. Al igual que en el caso anterior, se encuentra el
using al proyecto de Datos.
Clase Clientes_D:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace Datos
{
public class Clientes_D
{
string sqlStr;
string sError;
static string StrCnn = "data source=MLLARIN-NB\\SQL2008;initial catalog=Repeater;User Id=sa;password=sa;Trusted_Connection=False";
public string Buscar_Todos(ref DataTable pS_dt)
{
try
{
SqlConnection conn = new SqlConnection(StrCnn);
DataSet ds = new DataSet();
conn.ConnectionString = StrCnn;
SqlCommand comm = new SqlCommand("Clientes_Buscar_Todos", conn);
comm.CommandTimeout = 600;
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(comm);
da.Fill(ds);
pS_dt = ds.Tables[0];
conn.Close();
conn = null;
comm.Dispose();
return "";
}
catch (System.Exception ex)
{
return ex.Message;
throw;
}
}
}
}
Ahora que tenemos todo
el código podremos ver al ejecutar nuestro código algo de la siguiente forma:
Ahora, para poder
acceder a los controles que se encuentran dentro del Repeater para por ejemplo:
-
Poner un mensaje personalizado en el ImageButton
para eliminar.
-
Poder encontrar que cliente está dado de baja,
obteniendo el valor del checkbox.
-
Recuperar el Nombre de Fantasía de un cliente.
-
Cambiar la imagen del ImageButton.
Veamos cómo hacer esto:
El control Repeater
tiene una serie de eventos con los que es posible detectar varias cosas.
En principio para poder
hacer los 4 puntos que marcamos vamos a ver los eventos ItemDataBound e
ItemCommand.
El siguiente código me servirá para poder
cambiarle la imagen al ImageButton y poder definir mensajes personalizados al
momento de ser presionado. Como mensaje personalizado le pondremos que pregunte
si está seguro que desea eliminar al cliente: “Nombre de Fantasía”, donde el Nombre
de Fantasía lo obtendremos del origen de datos.
protected void rptClientes_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item; // elemento del Repeater
if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item)
{
ImageButton imgBtnEliminar = (ImageButton)item.FindControl("imgBtnEliminar"); // obtenemos el control.
// Como todavía no tiene definido el nombre de fantasía en el control, debemos acceder a este por medio de este código.
string NombreFantasia = ((System.Data.DataRowView)(item.DataItem)).Row.ItemArray[1].ToString(); // obtenemos el control.
CheckBox chkDadoDeBaja = (CheckBox)item.FindControl("chkDadoDeBaja"); // obtenemos el control checkbox.
// Detectamos cuando el cliente no se encuentra eliminado, entonces mostramos la imágen para eliminar.
if (!chkDadoDeBaja.Checked)
{
imgBtnEliminar.Visible = true; // le indico al botón que sea visible.
// acá agregamos el evento OnClientClick y le indicamos el mensaje que queremos aparezca cuando se haga clic con el
// mouse sobre este elemento
imgBtnEliminar.OnClientClick = "return confirm('Esta seguro que desea eliminar al cliente: " + NombreFantasia + " ?')";
imgBtnEliminar.ToolTip = "Eliminar";
// Cambiamos la imagen.
imgBtnEliminar.ImageUrl = "~/Images/Eliminar.png";
}
else
{
imgBtnEliminar.Visible = false; // le indico al botón que este oculto.
}
}
}
Los 4 puntos los pudimos
resolver solo con el evento ItemDataBound. Ahora veamos el evento ItemCommand.
protected void rptClientes_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Eliminar")
{
try
{
// Podriamos crear un método para eliminar los clientes
// El elemento e.CommandArgument.ToString() me trae el CommandArgument definido en el código html de
// la página aspx. En nuestro código guardamos el IdCliente, con lo cual lo podríamos utilizar para
// eliminar el cliente seleccionado.
}
catch (Exception ex)
{
string msg = "<script type='text/javascript'>alert('" + ex.Message + "');</script>";
Page.ClientScript.RegisterClientScriptBlock(GetType(), "Error", msg);
}
}
}
Con esto creo que
terminamos con lo propuesto en esta entrada.
Les dejo el código para su descarga: Descargar
Saludos,