Botones personalizados en los controles DataList y Repeater (C#)

por Scott Mitchell

Descargar PDF

En este tutorial, crearemos una interfaz que use repeater para enumerar las categorías del sistema, con cada categoría proporcionando un botón para mostrar sus productos asociados mediante un control BulletedList.

Introducción

En los últimos diecisiete tutoriales DataList y Repeater, hemos creado ejemplos de solo lectura y ejemplos de edición y eliminación. Para facilitar la edición y eliminación de funcionalidades dentro de una lista de datos, agregamos botones a la lista de datos que ItemTemplate, cuando se hace clic en ellos, provocaba un postback y generaba un evento DataList correspondiente a la propiedad CommandName del botón. Por ejemplo, agregar un botón al ItemTemplate con un valor de propiedad CommandName de Edit hace que los objetos DataList se EditCommand activen en postback; uno con Delete CommandName genera DeleteCommand.

Además de los botones Editar y Eliminar, los controles DataList y Repeater también pueden incluir Buttons, LinkButtons o ImageButtons que, cuando se hace clic, realizan alguna lógica personalizada del lado servidor. En este tutorial, crearemos una interfaz que use un Repeater para enumerar las categorías del sistema. Para cada categoría, Repeater incluirá un botón para mostrar los productos asociados de la categoría mediante un control BulletedList (Figura 1).

Clicking the Show Products Link Displays the Category s Products in a Bulleted List

Figura 1: al hacer clic en el vínculo Mostrar productos, se muestran los productos de categoría en una lista con viñetas (haga clic para ver la imagen a tamaño completo)

Paso 1: agregar las páginas web del tutorial de botón personalizado

Antes de ver cómo agregar un botón personalizado, vamos a tardar un momento en crear las páginas de ASP.NET en nuestro proyecto de sitio web que necesitaremos para este tutorial. Empiece agregando una nueva carpeta denominada CustomButtonsDataListRepeater. Luego, agregue las siguientes dos páginas ASP.NET a esa carpeta, asegurándose de asociar cada página a la página maestra Site.master:

  • Default.aspx
  • CustomButtons.aspx

Add the ASP.NET Pages for the Custom Buttons-Related Tutorials

Figura 2: agregar las páginas ASP.NET para los tutoriales sobre botones personalizados

Igual que en las otras carpetas, Default.aspx en la carpeta CustomButtonsDataListRepeater enumerará los tutoriales en su sección. Recuerde que el control de usuario SectionLevelTutorialListing.ascx proporciona esta funcionalidad. Por lo tanto, agregue este Control de usuario a Default.aspx arrastrándolo desde el Explorador de soluciones a la Vista de diseño de la página.

Add the SectionLevelTutorialListing.ascx User Control to Default.aspx

Figura 3: agregar el control de usuario SectionLevelTutorialListing.ascx a Default.aspx (haga clic aquí para ver la imagen a tamaño completo)

Por último, agregue las siguientes páginas como entradas al archivo Web.sitemap. En concreto, agregue el marcado siguiente después de la paginación y la ordenación con DataList y Repeater <siteMapNode>:

<siteMapNode
    url="~/CustomButtonsDataListRepeater/Default.aspx"
    title="Adding Custom Buttons to the DataList and Repeater"
    description="Samples of DataList and Repeater Reports that Include
                  Buttons for Performing Server-Side Actions">
    <siteMapNode
        url="~/CustomButtonsDataListRepeater/CustomButtons.aspx"
        title="Using Custom Buttons in the DataList and Repeater's Templates"
        description="Examines how to add custom Buttons, LinkButtons,
                      or ImageButtons within templates." />
</siteMapNode>

Después de actualizar Web.sitemap, dedique un momento a ver el sitio web de tutoriales en un explorador. El menú de la izquierda ahora incluye elementos para la edición, inserción y eliminación de tutoriales.

The Site Map Now Includes the Entry for the Custom Buttons Tutorial

Figura 4: el mapa del sitio ahora incluye la entrada para el tutorial sobre botones personalizados

Paso 2: agregar la lista de categorías

Para este tutorial, es necesario crear un repetidor que muestre todas las categorías junto con un botón Mostrar vínculo de productos que, cuando se hace clic en ellos, muestra los productos de la categoría asociada en una lista con viñetas. Vamos a crear primero un repetidor simple que enumera las categorías del sistema. Para empezar, abra la página CustomButtons.aspx en la carpeta CustomButtonsDataListRepeater. Arrastre un repetidor desde el cuadro de herramientas hasta el Diseñador y establezca su propiedad ID en Categories. A continuación, cree un nuevo control de origen de datos a partir de la etiqueta inteligente del repetidor. En concreto, cree un nuevo control ObjectDataSource denominado CategoriesDataSource que seleccione sus datos del método GetCategories() de la clase CategoriesBLL.

Configure the ObjectDataSource to Use the CategoriesBLL Class s GetCategories() Method

Figura 5: configurar ObjectDataSource para usar el método GetCategories() de la clase CategoriesBLL (haga clic para ver la imagen a tamaño completo)

A diferencia del control DataList, para el que Visual Studio crea un valor predeterminado ItemTemplate basado en el origen de datos, se deben definir manualmente las plantillas del repetidor. Además, las plantillas del repetidor deben crearse y editarse declarativamente (es decir, no hay ninguna opción Editar plantillas en la etiqueta inteligente del repetidor).

Haga clic en la pestaña Origen de la esquina inferior izquierda y agregue un ItemTemplate que muestre el nombre de la categoría en un elemento <h3> y su descripción en una etiqueta de párrafo; incluya un SeparatorTemplate que muestre una regla horizontal (<hr />) entre cada categoría. Agregue también un LinkButton con su propiedad Text establecida en Mostrar productos. Después de completar estos pasos, el marcado declarativo de la página debe ser similar al siguiente:

<asp:Repeater ID="Categories" DataSourceID="CategoriesDataSource"
    runat="server">
    <ItemTemplate>
        <h3><%# Eval("CategoryName") %></h3>
        <p>
            <%# Eval("Description") %>
            [<asp:LinkButton runat="server" ID="ShowProducts">
                Show Products</asp:LinkButton>]
        </p>
    </ItemTemplate>
    <SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

En la ilustración 6 se muestra la página cuando se ve a través de un explorador. Se muestra cada nombre de categoría y descripción. Cuando se hace clic en el botón Mostrar productos, se provoca una devolución de entrada, pero no realiza ninguna acción.

Each Category s Name and Description is Displayed, Along with a Show Products LinkButton

Figura 6: se muestra cada nombre y descripción de cada categoría, junto con un botón Mostrar vínculo de productos (haga clic para ver la imagen a tamaño completo)

Paso 3: ejecutar lógica del lado servidor cuando se hace clic en el botón Mostrar vínculos de productos

Cada vez que se hace clic en Button, LinkButton o ImageButton dentro de una plantilla de dataList o Repeater, se produce un postback y se desencadena el evento DataList o Repeater ItemCommand. Además del evento ItemCommand, el control DataList también puede generar otro evento más específico si la propiedad del botón s CommandName está establecida en una de las cadenas reservadas ( Delete, Edit, Cancel, Update o Select ), pero el evento ItemCommandsiempre se desencadena.

Cuando se hace clic en un botón en una DataList o Repeater, a menudo es necesario pasar el botón en el que se hizo clic (en el caso de que haya varios botones dentro del control, como un botón Editar y Eliminar) y quizás alguna información adicional (como el valor de clave principal del elemento cuyo botón se hizo clic). Button, LinkButton y ImageButton proporcionan dos propiedades cuyos valores se pasan al controlador de eventos ItemCommand:

  • CommandName una cadena que normalmente se usa para identificar cada botón de la plantilla
  • CommandArgument se usa normalmente para contener el valor de algunos campos de datos, como el valor de clave principal

En este ejemplo, establezca la propiedad LinkButton CommandName en ShowProducts y enlace el valor CategoryID de clave principal del registro actual a la CommandArgument propiedad mediante la sintaxisCategoryArgument='<%# Eval("CategoryID") %>' de enlace de datos. Después de especificar estas dos propiedades, la sintaxis declarativa de LinkButton debe ser similar a la siguiente:

<asp:LinkButton runat="server" CommandName="ShowProducts"
    CommandArgument='<%# Eval("CategoryID") %>' ID="ShowProducts">
    Show Products</asp:LinkButton>

Cuando se hace clic en el botón se produce una devolución de datos y se desencadena el evento ItemCommand de DataList o Repeater. El controlador de eventos se pasa a los valores CommandName y CommandArgument del botón.

Cree un controlador de eventos para el evento Repeater ItemCommand anote el segundo parámetro pasado al controlador de eventos (denominado e). Este segundo parámetro es de tipo RepeaterCommandEventArgs y tiene las cuatro propiedades siguientes:

  • CommandArgument el valor de la propiedad CommandArgument del botón en el que se ha hecho clic
  • CommandName el valor de la propiedad CommandName del botón
  • CommandSource una referencia al control de botón en el que se hizo clic
  • Item una referencia al RepeaterItem que contiene el botón al que se hizo clic; cada registro enlazado al Repeater se manifiesta como un RepeaterItem

Dado que CategoryID de la categoría seleccionada se pasa a través de la propiedad CommandArgument, podemos obtener el conjunto de productos asociados a la categoría seleccionada en el controlador de eventos ItemCommand. A continuación, estos productos se pueden enlazar a un control BulletedList en ItemTemplate (pendiente de agregar). Todo lo que queda es agregar BulletedList, hacer referencia a él en el controlador de eventos ItemCommand y enlazarlo al conjunto de productos para la categoría seleccionada, que abordaremos en el Paso 4.

Nota:

El controlador de eventos DataList ItemCommand se pasa a un objeto de tipo DataListCommandEventArgs, que ofrece las mismas cuatro propiedades que la clase RepeaterCommandEventArgs.

Paso 4: mostrar los productos de la categoría seleccionada en una lista con viñetas

Los productos de la categoría seleccionada se pueden mostrar dentro del ItemTemplate del Repeater mediante cualquier número de controles. Podríamos agregar otro Repeater anidado, una lista de datos, una lista desplegable, una clase GridView, etc. Como queremos mostrar los productos como una lista con viñetas, usaremos el control BulletedList. Al volver al marcado declarativo de la página CustomButtons.aspx, agregue un control BulletedList al ItemTemplate después del botón Show Products LinkButton. Establezca el ID de BulletedLists en ProductsInCategory. BulletedList muestra el valor del campo de datos especificado a través de la propiedad DataTextField; dado que este control tendrá la información del producto enlazada a él, establezca la propiedad DataTextField en ProductName.

<asp:BulletedList ID="ProductsInCategory" DataTextField="ProductName"
    runat="server"></asp:BulletedList>

En el ItemCommand controlador de eventos, haga referencia a este control mediante e.Item.FindControl("ProductsInCategory") y vincule al conjunto de productos asociados a la categoría seleccionada.

protected void Categories_ItemCommand(object source, RepeaterCommandEventArgs e)
{
    if (e.CommandName == "ShowProducts")
    {
        // Determine the CategoryID
        int categoryID = Convert.ToInt32(e.CommandArgument);
        // Get the associated products from the ProudctsBLL and bind
        // them to the BulletedList
        BulletedList products =
            (BulletedList)e.Item.FindControl("ProductsInCategory");
        ProductsBLL productsAPI = new ProductsBLL();
        products.DataSource =
            productsAPI.GetProductsByCategoryID(categoryID);
        products.DataBind());
    }
}

Antes de realizar cualquier acción en el ItemCommand controlador de eventos, es prudente comprobar primero el valor de la entrada CommandName. Dado que el ItemCommand controlador de eventos se activa cuando se hace clic en cualquier botón, si hay varios botones en la plantilla, use el CommandName valor para distinguir qué acción realizar. Comprobar aquí CommandName es moot, ya que solo tenemos un solo botón, pero es un buen hábito de formar. A continuación, se recupera el CategoryID de la categoría seleccionada de la propiedad CommandArgument. A continuación, se hace referencia al control BulletedList de la plantilla y se enlaza a los resultados de la clase ProductsBLL del método GetProductsByCategoryID(categoryID).

En tutoriales anteriores que usaban los botones dentro de una lista de datos, como Una introducción a la edición y eliminación de datos en DataList, determinamos el valor de clave principal de un elemento determinado a través de la colección DataKeys. Aunque este enfoque funciona bien con DataList, repeater no tiene una propiedad DataKeys. En su lugar, debemos usar un enfoque alternativo para proporcionar el valor de clave principal, como a través de la propiedad del botón o CommandArgument asignando el valor de clave principal a un control web de etiqueta oculto dentro de la plantilla y leyendo su valor de nuevo en el ItemCommand controlador de eventos mediante e.Item.FindControl("LabelID").

Después de completar el controlador de eventos ItemCommand, dedique un momento a probar la página en un explorador. Como se muestra en la Figura 7, al hacer clic en el vínculo Mostrar productos, se devuelve un postback y se muestran los productos de la categoría seleccionada en BulletedList. Además, tenga en cuenta que esta información del producto permanece, incluso si se hace clic en otras categorías Mostrar vínculos productos.

Nota:

Si desea modificar el comportamiento de este informe, de modo que los únicos productos de una categoría se muestran a la vez, simplemente establezca la propiedad False de control BulletedList en EnableViewState.

A BulletedList is used to Display the Products of the Selected Category

Figura 7: se usa una BulletedList para mostrar los productos de la categoría seleccionada (haga clic para ver la imagen a tamaño completo)

Resumen

Los controles DataList y Repeater pueden incluir cualquier número de botones, LinkButtons o ImageButtons dentro de sus plantillas. Estos botones, cuando se hace clic, provocan un postback y generan el evento ItemCommand. Para asociar la acción personalizada del lado servidor con un botón en el que se hace clic, cree un controlador de eventos para el evento ItemCommand. En este controlador de eventos, compruebe primero el valor entrante CommandName para determinar en qué botón se hizo clic. Opcionalmente, se puede proporcionar información adicional a través de la propiedad CommandArgument del botón.

¡Feliz programación!

Acerca del autor

Scott Mitchell, autor de siete libros de ASP/ASP.NET y fundador de 4GuysFromRolla.com, ha estado trabajando con tecnologías web de Microsoft desde 1998. Scott trabaja como consultor independiente, instructor y escritor. Su último libro es Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Puede ponerse en contacto con él en mitchell@4GuysFromRolla.com. o a través de su blog, http://ScottOnWriting.NET.

Agradecimientos especiales a

Esta serie de tutoriales contó con la revisión de muchos revisores que fueron de gran ayuda. El revisor principal de este tutorial fue Dennis Patterson. ¿Le interesa revisar mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4GuysFromRolla.com.