Mostrar datos con los controles DataList y Repeater (C#)

por Scott Mitchell

Descargar PDF

En los tutoriales anteriores se ha usado el control GridView para mostrar datos. A partir de este tutorial, se examina la creación de patrones de informes comunes con los controles DataList y Repeater, empezando por los conceptos básicos de mostrar datos con estos controles.

Introducción

En todos los ejemplos de los últimos 28 tutoriales, si era necesario mostrar varios registros de un origen de datos, se recurría al control GridView. GridView representa una fila para cada registro del origen de datos y muestra los campos de datos del registro en columnas. Aunque GridView hace que sea sencillo para mostrar, paginar, ordenar, editar y eliminar datos, su apariencia es algo tosca. Además, el marcado responsable de la estructura de GridView es fijo, incluye un elemento <table> HTML con una fila de tabla (<tr>) para cada registro y una celda de tabla (<td>) para cada campo.

Para proporcionar un mayor grado de personalización en la apariencia y marcado representado al mostrar varios registros, ASP.NET 2.0 ofrece los controles DataList y Repeater (también estaban disponibles en ASP.NET versión 1.x). Los controles DataList y Repeater representan su contenido mediante plantillas en lugar de controles BoundField, CheckBoxField, ButtonField, etc. Al igual que GridView, DataList se representa como un elemento <table> HTML, pero permite que se muestren varios registros de origen de datos por fila de tabla. Repeater, por otro lado, no representa ningún marcado adicional que especifique explícitamente y es un candidato ideal cuando necesita un control preciso sobre el marcado emitido.

En la próxima docena de tutoriales, verá cómo crear patrones de informes comunes con los controles DataList y Repeater, empezando por los conceptos básicos de mostrar datos con estas plantillas de controles. Verá cómo dar formato a estos controles, cómo modificar el diseño de los registros de origen de datos en DataList, escenarios comunes de maestro y detalles, formas de editar y eliminar datos, cómo paginar registros, etc.

Paso 1: Adición de las páginas web de los tutoriales sobre DataList y Repeater

Antes de comenzar este tutorial, dedicará un momento en agregar las páginas ASP.NET que necesitará para este tutorial y los siguientes que tratan sobre la representación de datos mediante DataList y Repeater. Para empezar, cree una carpeta en el proyecto con el nombre DataListRepeaterBasics. A continuación, agregue las cinco páginas ASP.NET siguientes a esta carpeta, todas ellas configuradas para usar la página maestra Site.master:

  • Default.aspx
  • Basics.aspx
  • Formatting.aspx
  • RepeatColumnAndDirection.aspx
  • NestedControls.aspx

Create a DataListRepeaterBasics Folder and Add the Tutorial ASP.NET Pages

Figura 1: Creación de una carpeta DataListRepeaterBasics y adición de las páginas ASP.NET del tutorial

Abra la página Default.aspx y arrastre el Control de usuario SectionLevelTutorialListing.ascx desde la carpeta UserControls a la superficie Diseño. Este control de usuario, que se ha creado en el tutorial Páginas maestras y navegación del sitio, enumera el mapa del sitio y muestra esos tutoriales en la sección actual en una lista con viñetas.

Add the SectionLevelTutorialListing.ascx User Control to Default.aspx

Figura 2: Adición del control de usuario SectionLevelTutorialListing.ascx a Default.aspx (Haga clic para ver la imagen a tamaño completo)

Para que la lista con viñetas muestre los tutoriales de DataList y Repeater que se van a crear, es necesario agregarlos al mapa del sitio. Abra el archivo Web.sitemap y agregue el marcado siguiente después del marcado del nodo del mapa del sitio Adición de botones personalizados:

<siteMapNode
    title="Displaying Data with the DataList and Repeater"
    description="Samples of Reports that Use the DataList and Repeater Controls"
    url="~/DataListRepeaterBasics/Default.aspx" >
    <siteMapNode
        title="Basic Examples"
        description="Examines the basics for displaying data using the
                      DataList and Repeater controls."
        url="~/DataListRepeaterBasics/Basics.aspx"  />
    <siteMapNode
        title="Formatting"
        description="Learn how to format the DataList and the Web controls within
                      the DataList and Repeater's templates."
        url="~/DataListRepeaterBasics/Formatting.aspx" />
    <siteMapNode
        title="Adjusting the DataList s Layout"
        description="Illustrates how to alter the DataList's layout, showing
                      multiple data source records per table row."
        url="~/DataListRepeaterBasics/RepeatColumnAndDirection.aspx" />
    <siteMapNode
        title="Nesting a Repeater within a DataList"
        description="Learn how to nest a Repeater within the template of a DataList."
        url="~/DataListRepeaterBasics/NestedControls.aspx" />
</siteMapNode>

Update the Site Map to Include the New ASP.NET Pages

Figura 3: Actualización del mapa del sitio para incluir las nuevas páginas ASP.NET

Paso 2: Representación de información del producto en DataList

De forma similar a FormView, la salida representada del control DataList depende de plantillas en lugar de controles BoundField, CheckBoxField, etc. A diferencia de FormView, DataList está diseñado para mostrar un conjunto de registros en lugar de uno solo. Para comenzar este tutorial se examinará el enlace de la información del producto a un control DataList. Para empezar, abra la página Basics.aspx en la carpeta DataListRepeaterBasics. A continuación, arrastre un control DataList desde el cuadro de herramientas al diseñador. Como se muestra en la figura 4, antes de especificar las plantillas de DataList, el Diseñador la muestra como un cuadro gris.

Drag the DataList From the Toolbox Onto the Designer

Figura 4: Arrastre de DataList desde el Cuadro de herramientas al Diseñador (Haga clic para ver la imagen a tamaño completo)

En la etiqueta inteligente de DataList, agregue un nuevo objeto ObjectDataSource y configúrelo para usar el método GetProducts de la clase ProductsBLL. Como en este tutorial se va a crear un control DataList de solo lectura, establezca la lista desplegable en (None) en las pestañas INSERT, UPDATE y DELETE del asistente.

Opt to Create a New ObjectDataSource

Figura 5: Creación de un elemento ObjectDataSource (Haga clic para ver la imagen a tamaño completo)

Configure the ObjectDataSource to Use the ProductsBLL Class

Figura 6: Configuración de ObjectDataSource para usar la clase ProductsBLL (Haga clic para ver la imagen a tamaño completo)

Retrieve Information About All of the Products Using the GetProducts Method

Figura 7: Recuperación de información sobre todos los productos mediante el método GetProducts (Haga clic para ver la imagen a tamaño completo)

Después de configurar ObjectDataSource y asociarlo a DataList desde su etiqueta inteligente, Visual Studio creará automáticamente un a instancia de ItemTemplate en DataList que muestra el nombre y el valor de cada campo de datos devuelto por el origen de datos (vea el marcado siguiente). La apariencia del elemento ItemTemplate predeterminado es idéntica a la de las plantillas creadas automáticamente al enlazar un origen de datos a FormView desde el Diseñador.

<asp:DataList ID="DataList1" runat="server" DataKeyField="ProductID"
    DataSourceID="ObjectDataSource1" EnableViewState="False">
    <ItemTemplate>
        ProductID:       <asp:Label ID="ProductIDLabel" runat="server"
                            Text='<%# Eval("ProductID") %>' /><br />
        ProductName:     <asp:Label ID="ProductNameLabel" runat="server"
                            Text='<%# Eval("ProductName") %>' /><br />
        SupplierID:      <asp:Label ID="SupplierIDLabel" runat="server"
                            Text='<%# Eval("SupplierID") %>' /><br />
        CategoryID:      <asp:Label ID="CategoryIDLabel" runat="server"
                            Text='<%# Eval("CategoryID") %>'/><br />
        QuantityPerUnit: <asp:Label ID="QuantityPerUnitLabel" runat="server"
                            Text='<%# Eval("QuantityPerUnit") %>' /><br />
        UnitPrice:       <asp:Label ID="UnitPriceLabel" runat="server"
                            Text='<%# Eval("UnitPrice") %>' /><br />
        UnitsInStock:    <asp:Label ID="UnitsInStockLabel" runat="server"
                            Text='<%# Eval("UnitsInStock") %>' /><br />
        UnitsOnOrder:    <asp:Label ID="UnitsOnOrderLabel" runat="server"
                            Text='<%# Eval("UnitsOnOrder") %>' /><br />
        ReorderLevel:    <asp:Label ID="ReorderLevelLabel" runat="server"
                            Text='<%# Eval("ReorderLevel") %>' /><br />
        Discontinued:    <asp:Label ID="DiscontinuedLabel" runat="server"
                            Text='<%# Eval("Discontinued") %>' /><br />
        CategoryName:    <asp:Label ID="CategoryNameLabel" runat="server"
                            Text='<%# Eval("CategoryName") %>' /><br />
        SupplierName:    <asp:Label ID="SupplierNameLabel" runat="server"
                            Text='<%# Eval("SupplierName") %>' /><br />
        <br />
    </ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>

Nota:

Recuerde que al enlazar un origen de datos a un control FormView desde la etiqueta inteligente de FormView, Visual Studio ha creado ItemTemplate, InsertItemTemplate y EditItemTemplate. Pero con DataList solo se crea una instancia de ItemTemplate. Esto se debe a que DataList no tiene la misma compatibilidad integrada de edición e inserción que ofrece FormView. DataList contiene eventos relacionados con la edición y eliminación, y la compatibilidad con la edición y eliminación se puede agregar con un poco de código, pero no hay compatibilidad sencilla lista para usar como con FormView. Verá cómo incluir compatibilidad con la edición y eliminación mediante DataList en un tutorial posterior.

Dedique un momento a mejorar la apariencia de esta plantilla. En lugar de mostrar todos los campos de datos, solo se mostrarán el nombre del producto, el proveedor, la categoría, la cantidad por unidad y el precio unitario. Además, se mostrará el nombre en un título <h4> y se diseñarán los campos restantes mediante un elemento <table> debajo del título.

Para realizar estos cambios, puede usar las características de edición de plantillas en el Diseñador; desde la etiqueta inteligente de DataList, haga clic en el vínculo Editar plantillas o puede modificar la plantilla manualmente con la sintaxis declarativa de la página. Si usa la opción Editar plantillas del Diseñador, es posible que el marcado resultante no coincida exactamente con el marcado siguiente, pero cuando se vea en un explorador debe ser muy similar a la captura de pantalla que se muestra en la figura 8.

<asp:DataList ID="DataList1" runat="server" DataKeyField="ProductID"
    DataSourceID="ObjectDataSource1" EnableViewState="False">
    <ItemTemplate>
        <h4><asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>' /></h4>
        <table border="0">
            <tr>
                <td class="ProductPropertyLabel">Category:</td>
                <td><asp:Label ID="CategoryNameLabel" runat="server"
                    Text='<%# Eval("CategoryName") %>' /></td>
                <td class="ProductPropertyLabel">Supplier:</td>
                <td><asp:Label ID="SupplierNameLabel" runat="server"
                    Text='<%# Eval("SupplierName") %>' /></td>
            </tr>
            <tr>
                <td class="ProductPropertyLabel">Qty/Unit:</td>
                <td><asp:Label ID="QuantityPerUnitLabel" runat="server"
                    Text='<%# Eval("QuantityPerUnit") %>' /></td>
                <td class="ProductPropertyLabel">Price:</td>
                <td><asp:Label ID="UnitPriceLabel" runat="server"
                    Text='<%# Eval("UnitPrice", "{0:C}") %>' /></td>
            </tr>
        </table>
    </ItemTemplate>
</asp:DataList>

Nota:

En el ejemplo anterior se usan controles web Label a cuya Text propiedad se le asigna el valor de la sintaxis de enlace de datos. Como alternativa, podría haber omitido las etiquetas por completo y escribir solo la sintaxis de enlace de datos. Es decir, en lugar de usar <asp:Label ID="CategoryNameLabel" runat="server" Text='<%# Eval("CategoryName") %>' />, podría haber usado la sintaxis declarativa <%# Eval("CategoryName") %>.

Pero dejar los controles web Label ofrece dos ventajas. En primer lugar, proporciona un medio más sencillo para dar formato a los datos en función de los datos, como verá en el siguiente tutorial. En segundo lugar, la opción Editar plantillas del Diseñador no muestra la sintaxis declarativa de enlace de datos que aparece fuera de algún control web. En su lugar, la interfaz Editar plantillas está diseñada para facilitar el trabajo con controles web y marcado estático, y asume que cualquier enlace de datos se realizará desde el cuadro de diálogo Editar DataBindings, al que se puede acceder desde las etiquetas inteligentes de los controles web.

Por tanto, al trabajar con DataList, que proporciona la opción de editar las plantillas desde el Diseñador, es preferible usar controles web de etiqueta para que el contenido sea accesible desde la interfaz Editar plantillas. Como verá en breve, el control Repeater requiere que el contenido de la plantilla se edite desde la vista Origen. Por tanto, al crear las plantillas de Repeater, a menudo se omitirán los controles web de etiqueta a menos que sea necesario dar formato a la apariencia del texto enlazado a datos en función de la lógica de programación.

Each Product s Output is Rendered Using the DataList s ItemTemplate

Figura 8: Cada salida del producto se representa mediante ItemTemplate del control DataList (Haga clic para ver la imagen a tamaño completo)

Paso 3: Mejora de la apariencia de DataList

Al igual que GridView, DataList ofrece una serie de propiedades relacionadas con el estilo, como Font, ForeColor, BackColor, CssClass, ItemStyle, AlternatingItemStyle, SelectedItemStyle, etc. Al trabajar con los controles GridView y DetailsView, se crean archivos de máscara en el tema DataWebControls que definen previamente las propiedades CssClass de estos dos controles y la propiedad CssClass para varias de sus subpropiedades (RowStyle, HeaderStyle, etc.). Ahora hará lo mismo para DataList.

Como se ha descrito en el tutorial Representación de datos con ObjectDataSource, un archivo de máscara especifica las propiedades predeterminadas relacionadas con la apariencia de un control web; un tema es una colección de archivos de máscara, CSS, imagen y JavaScript que definen una apariencia determinada para un sitio web. En el tutorial Representación de datos con ObjectDataSource, se ha creado un tema DataWebControls (que se implementa como una carpeta dentro de la carpeta App_Themes) que tiene, actualmente, dos archivos de máscara: GridView.skin y DetailsView.skin. Ahora agregará un tercer archivo de máscara para especificar la configuración de estilo predefinida para DataList.

Para agregar un archivo de máscara, haga clic con el botón derecho en la carpeta App_Themes/DataWebControls, elija Agregar un nuevo elemento y seleccione la opción Archivo de máscara en la lista. Asigne al archivo el nombre DataList.skin.

Screenshot showing the Add New Item window with Default.skin entered as the new Skin file name.

Figura 9: Creación de un archivo de máscara denominado DataList.skin (Haga clic para ver la imagen a tamaño completo)

Use el marcado siguiente para el archivo DataList.skin:

<asp:DataList runat="server" CssClass="DataWebControlStyle">
   <AlternatingItemStyle CssClass="AlternatingRowStyle" />
   <ItemStyle CssClass="RowStyle" />
   <HeaderStyle CssClass="HeaderStyle" />
   <FooterStyle CssClass="FooterStyle" />
   <SelectedItemStyle CssClass="SelectedRowStyle" />
</asp:DataList>

Estos valores asignan las mismas clases CSS a las propiedades de DataList adecuadas como con los controles GridView y DetailsView. Las clases CSS usadas aquí DataWebControlStyle, AlternatingRowStyle, RowStyle, etc., se definen en el archivo Styles.css y se agregaron en tutoriales anteriores.

Con la adición de este archivo de máscara, la apariencia de DataList se actualiza en el Diseñador (es posible que tenga que actualizar la vista Diseñador para ver los efectos del nuevo archivo de máscara; en el menú Ver, elija Actualizar). Como se muestra en la figura 10, cada producto alterno tiene un color de fondo rosa claro.

Screenshot showing how the new Skin file updates the appearance of DataList in the Designer.

Figura 10: Creación de un archivo de máscara denominado DataList.skin (Haga clic para ver la imagen a tamaño completo)

Paso 4: Exploración de otras plantillas de DataList

Además de ItemTemplate, DataList admite otras seis plantillas opcionales:

  • HeaderTemplate si se proporciona, agrega una fila de encabezado a la salida y se usa para representar esta fila
  • AlternatingItemTemplate se usa para representar elementos alternos
  • SelectedItemTemplate se usa para representar el elemento seleccionado; el elemento seleccionado es el elemento cuyo índice se corresponde a la propiedad SelectedIndex de DataList
  • EditItemTemplate se usa para representar el elemento que se edita
  • SeparatorTemplate si se proporciona, agrega un separador entre cada elemento y se usa para representar este separador
  • FooterTemplate: si se proporciona, agrega una fila de pie de página a la salida y se usa para representar esta fila

Al especificar HeaderTemplate o FooterTemplate, DataList agrega una fila de encabezado o pie de página adicional a la salida representada. Al igual que con las filas de encabezado y pie de página de GridView, el encabezado y el pie de página de un control DataList no están enlazados a los datos. Por tanto, cualquier sintaxis de enlace de datos en HeaderTemplate o FooterTemplate que intente acceder a los datos enlazados devolverá una cadena en blanco.

Nota:

Como ha visto en el tutorial Representación de información de resumen en el pie de página de GridView, mientras que las filas de encabezado y pie de página no admiten la sintaxis de enlace de datos, la información específica de los datos se puede insertar directamente en estas filas desde el controlador de eventos RowDataBound de GridView. Esta técnica se puede usar para calcular totales acumulados u otra información de los datos enlazados al control, así como para asignar esa información al pie de página. Este mismo concepto se puede aplicar a los controles DataList y Repeater; la única diferencia es que para DataList y Repeater se crea un controlador de eventos para el evento ItemDataBound (en lugar de para el evento RowDataBound).

En este ejemplo, el título Información del producto se mostrará en la parte superior de DataList, lo que da como resultado un título <h3>. Para ello, agregue un elemento HeaderTemplate con el marcado adecuado. En el Diseñador, esto se puede lograr si hace clic en el vínculo Editar plantillas de la etiqueta inteligente de DataList, elige la plantilla de encabezado en la lista desplegable y escribe el texto después de seleccionar la opción Título 3 en la lista desplegable estilo (vea la figura 11).

Add a HeaderTemplate with the Text Product Information

Figura 11: Adición de HeaderTemplate con la información del producto de texto (Haga clic para ver la imagen a tamaño completo)

Como alternativa, esto se puede agregar mediante declaración si escribe el marcado siguiente dentro de las etiquetas <asp:DataList>:

<HeaderTemplate>
   <h3>Product Information</h3>
</HeaderTemplate>

Para agregar un poco de espacio entre cada lista de productos, se agregará un elemento SeparatorTemplate que incluye una línea entre cada sección. La etiqueta de regla horizontal (<hr>), agrega ese tipo de divisor. Cree SeparatorTemplate con el marcado siguiente:

<SeparatorTemplate>
    <hr />
</SeparatorTemplate>

Nota:

Al igual que HeaderTemplate y FooterTemplates, SeparatorTemplate no está enlazado a ningún registro del origen de datos y, por tanto, no puede acceder directamente a los registros de origen de datos enlazados a DataList.

Después de realizar esta adición, al ver la página en un explorador, debería ser similar a la figura 12. Observe la fila de encabezado y la línea entre cada lista de productos.

The DataList Includes a Header Row and a Horizontal Rule Between Each Product Listing

Figura 12: DataList incluye una fila de encabezado y una regla horizontal entre cada lista de productos (Haga clic para ver la imagen a tamaño completo)

Paso 5: Representación de marcado específico con el control Repeater

Si ejecuta Ver/Origen desde el explorador al visitar el ejemplo DataList de la figura 12, verá que DataList emite un elemento <table> HTML que contiene una fila de tabla (<tr>) con una sola celda de tabla (<td>) para cada elemento enlazado a DataList. Esta salida, de hecho, es idéntica a la que se emitiría desde GridView con un único objeto TemplateField. Como verá en un tutorial posterior, DataList permite una mayor personalización de la salida, lo que permite mostrar varios registros de origen de datos por fila de tabla.

¿Qué ocurre si no quiere emitir un elemento <table> HTML? Para un control total y completo sobre el marcado generado por un control web de datos, debe usar el control Repeater. Al igual que DataList, el control Repeater se construye en función de las plantillas. Pero el control Repeater solo ofrece las cinco plantillas siguientes:

  • HeaderTemplate si se proporciona, agrega el marcado especificado antes de los elementos
  • ItemTemplate se usa para representar elementos
  • AlternatingItemTemplate si se proporciona, se usa para representar elementos alternos
  • SeparatorTemplate si se proporciona, agrega el marcado especificado entre cada elemento
  • FooterTemplate: si se proporciona, agrega el marcado especificado después de los elementos

En ASP.NET 1.x, el control Repeater se usaba normalmente para mostrar una lista con viñetas cuyos datos provenían de un origen de datos. En e caso, HeaderTemplate y FooterTemplates contendrán las etiquetas <ul> de apertura y cierre, respectivamente, mientras que ItemTemplate contendrán los elementos <li> con sintaxis de enlace de datos. Este enfoque todavía se puede usar en ASP.NET 2.0, como ha visto en dos ejemplos del tutorial Páginas maestras y navegación del sitio:

  • En la página maestra Site.master, se ha usado un control Repeater para mostrar una lista con viñetas del contenido del mapa del sitio de nivel superior (informes básicos, informes de filtrado, formato personalizado, etc.); se ha usado otro control Repeater anidado para mostrar las secciones secundarias de las secciones de nivel superior
  • En SectionLevelTutorialListing.ascx, se ha usado un control Repeater para mostrar una lista con viñetas de las secciones secundarias de la sección de mapa del sitio actual

Nota:

En ASP.NET 2.0 se presenta el nuevo control BulletedList, que se puede enlazar a un control de origen de datos para mostrar una lista simple con viñetas. Con el control BulletedList no es necesario especificar código HTML relacionado con listas; en su lugar, simplemente se indica el campo de datos que se va a mostrar como texto para cada elemento de lista.

El control Repeater actúa como un control web de captura de todos los datos. Si no hay un control existente que genere el marcado necesario, se puede usar el control Repeater. Para ilustrar el uso del control Repeater, la lista de categorías se mostrará encima del control DataList Product Information creado en el paso 2. En concreto, las categorías se mostrarán en un elemento <table> HTML de una sola fila, cada categoría como una columna de la tabla.

Para ello, primero arrastre un control Repeater desde el Cuadro de herramientas al Diseñador, encima del control DataList Product Information. Al igual que con DataList, el control Repeater se muestra inicialmente como un cuadro gris hasta que se hayan definido sus plantillas.

Add a Repeater to the Designer

Figura 13: Adición de un control Repeater al Diseñador (Haga clic para ver la imagen a tamaño completo)

Solo hay una opción en la etiqueta inteligente del control Repeater: elija Origen de datos. Puede crear un objeto ObjectDataSource y configurarlo para usar el método GetCategories de la clase CategoriesBLL.

Create a New ObjectDataSource

Figura 14: Creación de un elemento ObjectDataSource (Haga clic para ver la imagen a tamaño completo)

Configure the ObjectDataSource to Use the CategoriesBLL Class

Figura 15: Configuración de ObjectDataSource para usar la clase CategoriesBLL (Haga clic para ver la imagen a tamaño completo)

Retrieve Information About All of the Categories Using the GetCategories Method

Figura 16: Recuperación de información sobre todas las categorías mediante el método GetCategories (Haga clic para ver la imagen a tamaño completo)

A diferencia de DataList, Visual Studio no crea automáticamente un elemento ItemTemplate para el control Repeater después de enlazarlo a un origen de datos. Además, las plantillas del control Repeater no se pueden configurar desde el Diseñador y se deben especificar mediante declaración.

Para mostrar las categorías como un elemento <table> de una sola fila con una columna para cada categoría, es necesario que el control Repeater emita marcado similar al siguiente:

<table>
   <tr>
      <td>Category 1</td>
      <td>Category 2</td>
      ...
      <td>Category N</td>
   </tr>
</table>

Como el texto <td>Category X</td> es la parte que se repite, aparecerá en el elemento ItemTemplate del control Repeater. El marcado que aparece antes, <table><tr>, se colocará en HeaderTemplate mientras que el marcado final, </tr></table>, se colocará en FooterTemplate. Para especificar esta configuración de plantilla, vaya a la parte declarativa de la página ASP.NET; haga clic en el botón Origen de la esquina inferior izquierda y escriba la sintaxis siguiente:

<asp:Repeater ID="Repeater1" runat="server" DataSourceID="ObjectDataSource2"
    EnableViewState="False">
    <HeaderTemplate>
        <table>
            <tr>
    </HeaderTemplate>
    <ItemTemplate>
                <td><%# Eval("CategoryName") %></td>
    </ItemTemplate>
    <FooterTemplate>
            </tr>
        </table>
    </FooterTemplate>
</asp:Repeater>

El control Repeater emite el marcado preciso especificado por sus plantillas, solo eso. En la figura 17 se muestra la salida del control Repeater cuando se ve en un explorador.

A Single-Row HTML <table> Lists Each Category in a Separate Column

Figura 17: Una elemento <table> HTML de una sola fila enumera cada categoría en una columna independiente (Haga clic para ver la imagen a tamaño completo)

Paso 6: Mejora de la apariencia de Repeater

Como Repeater emite exactamente el marcado especificado por sus plantillas, no debería sorprenderle que no haya propiedades relacionadas con el estilo para Repeater. Para modificar la apariencia del contenido generado por Repeater, debe agregar manualmente el contenido HTML o CSS necesario directamente a sus plantillas.

En este ejemplo, las columnas de categoría tendrán colores de fondo alternos, como en las filas alternas de DataList. Para ello, es necesario asignar la clase CSS RowStyle a cada elemento Repeater y la clase CSS AlternatingRowStyle a cada elemento Repeater alterno mediante las plantillas ItemTemplate y AlternatingItemTemplate, de la siguiente manera:

<ItemTemplate>
    <td class="RowStyle"><%# Eval("CategoryName") %></td>
</ItemTemplate>
<AlternatingItemTemplate>
    <td class="AlternatingRowStyle"><%# Eval("CategoryName") %></td>
</AlternatingItemTemplate>

Ahora también se agregará una fila de encabezado a la salida con el texto Categorías de producto. Como no se sabe cuántas columnas tendrá el elemento <table> resultante, la manera más sencilla de generar una fila de encabezado que abarque todas las columnas es usar dos elementos <table>s. El primer elemento <table> contendrá dos filas, la fila de encabezado y una fila que contendrá el segundo elemento <table> de una sola fila con una columna para cada categoría del sistema. Es decir, se quiere emitir el marcado siguiente:

<table>
   <tr>
      <th>Product Categories</th>
   </tr>
   <tr>
      <td>
         <table>
            <tr>
               <td>Category 1</td>
               <td>Category 2</td>
               ...
               <td>Category N</td>
            </tr>
         </table>
      </td>
   </tr>
</table>

Las instancias de HeaderTemplate y FooterTemplate siguientes crean el marcado deseado:

<asp:Repeater ID="Repeater1" runat="server" DataSourceID="ObjectDataSource2"
    EnableViewState="False">
    <HeaderTemplate>
        <table cellpadding="0" cellspacing="0">
            <tr>
                <th class="HeaderStyle">Product Categories</th>
            </tr>
            <tr>
                <td>
                    <table cellpadding="4" cellspacing="0">
                        <tr>
    </HeaderTemplate>
    <ItemTemplate>
                            <td class="RowStyle"><%# Eval("CategoryName") %></td>
    </ItemTemplate>
    <AlternatingItemTemplate>
                            <td class="AlternatingRowStyle">
                                <%# Eval("CategoryName") %></td>
    </AlternatingItemTemplate>
    <FooterTemplate>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
    </FooterTemplate>
</asp:Repeater>

En la figura 18 se muestra el control Repeater después de realizar estos cambios.

The Category Columns Alternate in Background Color and Includes a Header Row

Figura 18: Columnas de categoría con colores de fondo alternos y una fila de encabezado (Haga clic para ver la imagen a tamaño completo)

Resumen

Aunque el control GridView facilita la visualización, edición, eliminación, ordenación y paginación por los datos, la apariencia es muy tosca, similar a una cuadrícula. Para obtener más control sobre la apariencia, es necesario recurrir a los controles DataList o Repeater. Los dos controles muestran un conjunto de registros con plantillas en lugar de controles BoundField, CheckBoxField, etc.

DataList se representa como un elemento <table> HTML que, de forma predeterminada, muestra cada registro del origen de datos en una sola fila de tabla, al igual que GridView con un solo objeto TemplateField. Pero como verá en un tutorial posterior, DataList permite mostrar varios registros por fila de tabla. Por otro lado, Repeater emite estrictamente el marcado especificado en sus plantillas; no agrega ningún marcado adicional y, por tanto, se usa normalmente para mostrar datos en elementos HTML distintos de <table> (por ejemplo, en una lista con viñetas).

Aunque DataList y Repeater ofrecen más flexibilidad en la salida que representan, carecen de muchas de las características integradas que se encuentran en GridView. Como se verá en los próximos tutoriales, algunas de estas características se pueden agregar sin demasiado esfuerzo, pero tenga en cuenta que el uso de DataList o Repeater en lugar de GridView limita las características que puede usar sin tener que implementarlas personalmente.

¡Feliz programación!

Acerca del autor

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

Agradecimientos especiales a

Esta serie de tutoriales fue revisada por muchos revisores. Los revisores principales de este tutorial han sido Yaakov Ellis, Liz Shulok, Randy Schmidt y Stacy Park. ¿Le interesaría revisar mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4GuysFromRolla.com.