Paginar datos de informe en un control DataList o Repeater (VB)

por Scott Mitchell

Descargar PDF

Aunque ni DataList ni Repeater ofrecen compatibilidad con la paginación u ordenación automáticas, en este tutorial se muestra cómo agregar compatibilidad de paginación a DataList o Repeater, lo que permite interfaces de paginación y visualización de datos mucho más flexibles.

Introducción

La paginación y la ordenación son dos características muy comunes al mostrar datos en una aplicación en línea. Por ejemplo, al buscar libros sobre ASP.NET en una librería en línea, puede haber cientos de libros de este tipo, pero en el informe que enumera los resultados de la búsqueda solo se muestran diez coincidencias por página. Además, los resultados se pueden ordenar por título, precio, número de páginas, nombre del autor, etc. Como se ha descrito en el tutorial Paginación y ordenación de datos de informe, los controles GridView, DetailsView y FormView proporcionan compatibilidad integrada de paginación que se puede habilitar al activar una casilla. GridView también incluye compatibilidad de ordenación.

Desafortunadamente, ni DataList ni Repeater ofrecen compatibilidad automática de paginación ni ordenación. En este tutorial se verá cómo agregar compatibilidad de paginación a DataList o Repeater. Debe crear manualmente la interfaz de paginación, mostrar la página de registros adecuada y recordar la página que se visita entre postbacks. Aunque para esto se necesita más tiempo y código que con GridView, DetailsView o FormView, DataList y Repeater permiten interfaces de visualización de datos y paginación mucho más flexibles.

Nota:

Este tutorial se centra exclusivamente en la paginación. En el siguiente tutorial, se centrará en la adición de funcionalidades de ordenación.

Paso 1: Adición de las páginas web del tutorial de paginación y ordenación

Antes de comenzar este tutorial, se agregarán las páginas ASP.NET necesarias para este tutorial y el siguiente. Empiece por crear una carpeta en el proyecto con el nombre PagingSortingDataListRepeater. 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
  • Paging.aspx
  • Sorting.aspx
  • SortingWithDefaultPaging.aspx
  • SortingWithCustomPaging.aspx

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

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

A continuación, 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 aquí para ver la imagen a tamaño completo)

Para que la lista con viñetas muestre los tutoriales de paginación y ordenación que se van a crear, es necesario agregarlos al mapa del sitio. Abra el archivoWeb.sitemap y agregue el marcado siguiente después del marcado del nodo de mapa del sitio Edición y eliminación con DataList:

<siteMapNode
    url="~/PagingSortingDataListRepeater/Default.aspx"
    title="Paging and Sorting with the DataList and Repeater"
    description="Paging and Sorting the Data in the DataList and Repeater Controls">
    <siteMapNode
        url="~/PagingSortingDataListRepeater/Paging.aspx"
        title="Paging"
        description="Learn how to page through the data shown
                     in the DataList and Repeater controls." />
    <siteMapNode
        url="~/PagingSortingDataListRepeater/Sorting.aspx"
        title="Sorting"
        description="Sort the data displayed in a DataList or
                     Repeater control." />
    <siteMapNode
        url="~/PagingSortingDataListRepeater/SortingWithDefaultPaging.aspx"
        title="Sorting with Default Paging"
        description="Create a DataList or Repeater control that is paged using
                     default paging and can be sorted." />
    <siteMapNode
        url="~/PagingSortingDataListRepeater/SortingWithCustomPaging.aspx"
        title="Sorting with Custom Paging"
        description="Learn how to sort the data displayed in a DataList or
                     Repeater control that uses custom paging." />
</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

Revisión de la paginación

En tutoriales anteriores ha visto cómo paginar por los datos en los controles GridView, DetailsView y FormView. Estos tres controles ofrecen una forma sencilla de paginación denominada paginación predeterminada que se puede implementar simplemente al activar la opción Habilitar paginación en la etiqueta inteligente del control. Con la paginación predeterminada, cada vez que se solicita una página de datos en la primera visita a la página o cuando el usuario navega a otra página de datos, el control GridView, DetailsView o FormView vuelve a solicitar todos los datos de ObjectDataSource. Después, recorta el conjunto determinado de registros para mostrar según el índice de página solicitado y el número de registros que se van a mostrar por página. La paginación predeterminada se ha descrito con detalle en el tutorial Paginación y ordenación de datos de informe.

Como la paginación predeterminada vuelve a solicitar todos los registros de cada página, no es práctico paginar por cantidades grandes de datos. Por ejemplo, imagine la paginación por 50 000 registros con un tamaño de página de 10. Cada vez que el usuario se mueve a una página nueva, se deben recuperar los 50 000 registros de la base de datos, aunque solo se muestren 10.

La paginación personalizada resuelve los problemas de rendimiento de la paginación predeterminada y captura solo el subconjunto preciso de registros que se van a mostrar en la página solicitada. Al implementar la paginación personalizada, debe escribir la consulta SQL que devolverá eficazmente solo el conjunto correcto de registros. Ha visto cómo crear una consulta de este tipo mediante la nueva palabra clave ROW_NUMBER() de SQL Server 2005 en el tutorial Paginación eficaz por grandes cantidades de datos.

Para implementar la paginación predeterminada en los controles DataList o Repeater, puede usar la clase PagedDataSource como contenedor alrededor de cuyo elemento ProductsDataTable se pagina el contenido. La clase PagedDataSource tiene una propiedad DataSource que se puede asignar a cualquier objeto enumerable y propiedades PageSize y CurrentPageIndex que indican el número de registros que se van a mostrar por página y el índice de página actual. Una vez que se establecen estas propiedades, se puede usar PagedDataSource como origen de datos de cualquier control web de datos. Cuando se enumera PagedDataSource, solo devolverá el subconjunto adecuado de registros de su elemento DataSource interno en función de las propiedades PageSize y CurrentPageIndex. En la figura 4 se muestra la funcionalidad de la clase PagedDataSource.

The PagedDataSource Wraps an Enumerable Object with a Pageable Interface

Figura 4: PagedDataSource encapsula un objeto enumerable con una interfaz de paginación

El objeto PagedDataSource se puede crear y configurar directamente desde la capa de lógica de negocios y enlazarlo a un control DataList o Repeater a desde ObjectDataSource, o bien se puede crear y configurar directamente en la clase de código subyacente de la página ASP.NET. Si usa el último enfoque, debe prescindir de ObjectDataSource y, en su lugar, enlazar los datos paginados al control DataList o Repeater mediante programación.

El objeto PagedDataSource también tiene propiedades para admitir la paginación personalizada. Pero se puede omitir el uso de PagedDataSource para la paginación personalizada porque ya hay métodos BLL en la clase ProductsBLL diseñados para la paginación personalizada que devuelven los registros precisos que se van a mostrar.

En este tutorial verá cómo implementar la paginación predeterminada en un control DataList mediante la adición de un nuevo método a la clase ProductsBLL que devuelve un objeto PagedDataSource configurado correctamente. En el siguiente tutorial, verá cómo usar la paginación personalizada.

Paso 2: Adición de un método de paginación predeterminada en la capa de lógica de negocios

La clase ProductsBLL tiene actualmente un método para devolver toda la información del producto GetProducts() y otro para devolver un subconjunto determinado de productos en un índice inicial GetProductsPaged(startRowIndex, maximumRows). Con la paginación predeterminada, los controles GridView, DetailsView y FormView usan el método GetProducts() para recuperar todos los productos, pero después usan una instancia de PagedDataSource interna para mostrar solo el subconjunto correcto de registros. Para replicar esta funcionalidad con los controles DataList y Repeater, puede crear un método en BLL que imite este comportamiento.

Agregue un método a la clase ProductsBLL con el nombre GetProductsAsPagedDataSource que tome dos parámetros de entrada enteros:

  • pageIndex el índice de la página que se va a mostrar, indexado en cero y
  • pageSize el número de registros que se van a mostrar por página.

GetProductsAsPagedDataSource comienza con la recuperación de todos los registros de GetProducts(). Después, crea un objeto PagedDataSource y establece sus propiedades CurrentPageIndex y PageSize en los valores de los parámetros pageIndex y pageSize que se han pasado. Para finalizar, el método devuelve este elemento PagedDataSource configurado:

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Select, False)> _
Public Function GetProductsAsPagedDataSource(ByVal pageIndex As Integer, _
    ByVal pageSize As Integer) As PagedDataSource
    ' Get ALL of the products
    Dim products As Northwind.ProductsDataTable = GetProducts()
    ' Limit the results through a PagedDataSource
    Dim pagedData As New PagedDataSource()
    pagedData.DataSource = products.Rows
    pagedData.AllowPaging = True
    pagedData.CurrentPageIndex = pageIndex
    pagedData.PageSize = pageSize
    Return pagedData
End Function

Paso 3: Representación de la información del producto en un control DataList mediante la paginación predeterminada

Con el método GetProductsAsPagedDataSource agregado a la clase ProductsBLL, ahora puede crear un control DataList o Repeater que proporcione la paginación predeterminada. Para empezar, abra la página Paging.aspx en la carpeta PagingSortingDataListRepeater y arrastre un control DataList desde el Cuadro de herramientas al Diseñador, y establezca la propiedad IDde DataList enProductsDefaultPaging. Desde la etiqueta inteligente de DataList, cree un objeto ObjectDataSource denominado ProductsDefaultPagingDataSource y configúrelo para que recupere los datos mediante el método GetProductsAsPagedDataSource.

Create an ObjectDataSource and Configure it to Use the GetProductsAsPagedDataSource () Method

Figura 5: Creación de ObjectDataSource y configuración para que use el método GetProductsAsPagedDataSource() (Haga clic para ver la imagen a tamaño completo)

Establezca las listas desplegables de las pestañas UPDATE, INSERT y DELETE en (None).

Set the Drop-Down Lists in the UPDATE, INSERT, and DELETE tabs to (None)

Figura 6: Establecimiento de las listas desplegables de las pestañas UPDATE, INSERT y DELETE en (None) (Haga clic para ver la imagen a tamaño completo)

Como el método GetProductsAsPagedDataSource espera dos parámetros de entrada, el asistente le pide el origen de estos valores de parámetro.

Los valores de índice de página y tamaño de página se deben recordar entre postbacks. Se pueden almacenar en el estado de visualización, conservarse en la cadena de consultas, almacenarse en variables de sesión o recordarse mediante otra técnica. En este tutorial, se usará la cadena de consulta, que tiene la ventaja de permitir que se marque una página determinada de datos.

En concreto, use los campos pageIndex y pageSize de querystring para los parámetros pageIndex y pageSize, respectivamente (vea la figura 7). Dedique un momento a establecer los valores predeterminados para estos parámetros, ya que los valores de cadena de consulta no estarán presentes cuando un usuario visite esta página por primera vez. Para pageIndex, establezca el valor predeterminado en 0 (que mostrará la primera página de datos) y el valor predeterminado de pageSize en 4.

Use the QueryString as the Source for the pageIndex and pageSize Parameters

Figura 7: Uso de QueryString como origen para los parámetros pageIndex y pageSize (Haga clic para ver la imagen a tamaño completo)

Después de configurar ObjectDataSource, Visual Studio crea automáticamente una instancia de ItemTemplate para DataList. Personalice ItemTemplate para que solo se muestren el nombre, la categoría y el proveedor del producto. Establezca también la propiedad RepeatColumns de DataList en 2,Width en 100 % y Width de ItemStyle en 50 %. Estos valores de ancho proporcionan un espaciado igual para las dos columnas.

Después de realizar estos cambios, el marcado de DataList y ObjectDataSource debe ser similar al siguiente:

<asp:DataList ID="ProductsDefaultPaging" runat="server" Width="100%"
    DataKeyField="ProductID" DataSourceID="ProductsDefaultPagingDataSource"
    RepeatColumns="2" EnableViewState="False">
    <ItemTemplate>
        <h4><asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>'></asp:Label></h4>
        Category:
        <asp:Label ID="CategoryNameLabel" runat="server"
            Text='<%# Eval("CategoryName") %>'></asp:Label><br />
        Supplier:
        <asp:Label ID="SupplierNameLabel" runat="server"
            Text='<%# Eval("SupplierName") %>'></asp:Label><br />
        <br />
        <br />
    </ItemTemplate>
    <ItemStyle Width="50%" />
</asp:DataList>
<asp:ObjectDataSource ID="ProductsDefaultPagingDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
    SelectMethod="GetProductsAsPagedDataSource">
    <SelectParameters>
        <asp:QueryStringParameter DefaultValue="0" Name="pageIndex"
             QueryStringField="pageIndex" Type="Int32" />
        <asp:QueryStringParameter DefaultValue="4" Name="pageSize"
             QueryStringField="pageSize" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

Nota:

Como en este tutorial no se realiza ninguna funcionalidad de actualización o eliminación, puede deshabilitar el estado de visualización de DataList para reducir el tamaño de página representado.

Al visitar inicialmente esta página desde un explorador, no se proporcionan los parámetros pageIndex ni pageSize de la cadena de consulta. Por tanto, se usan los valores predeterminados de 0 y 4. Como se muestra en la figura 8, esto da como resultado un control DataList que muestra los cuatro primeros productos.

The First Four Products are Listed

Figura 8: Se muestran los cuatro primeros productos (Haga clic para ver la imagen a tamaño completo)

Sin una interfaz de paginación, actualmente no hay ningún medio sencillo para que un usuario vaya a la segunda página de datos. En el paso 4 se creará una interfaz de paginación. Por ahora, la paginación solo se puede realizar si se especifican directamente los criterios de paginación en la cadena de consulta. Por ejemplo, para ver la segunda página, cambie la dirección URL en la barra de direcciones del explorador de Paging.aspx a Paging.aspx?pageIndex=2 y presione Entrar. Esto hace que se muestre la segunda página de datos (vea la figura 9).

Screenshot of the Paging Data in a DataList window showing the second page of data.

Figura 9: Se muestra la segunda página de datos (Haga clic para ver la imagen a tamaño completo)

Paso 4: Creación de la interfaz de paginación

Se pueden implementar varias interfaces de paginación diferentes. Los controles GridView, DetailsView y FormView proporcionan cuatro interfaces diferentes entre las que elegir:

  • Siguiente, Anterior los usuarios se pueden mover una página a la vez, a la siguiente o la anterior.
  • Siguiente, Anterior, Primera, Última además de los botones Siguiente y Anterior, esta interfaz incluye los botones Primera y Última para pasar a la primera página o la última.
  • Numérico muestra los números de página en la interfaz de paginación, lo que permite al usuario saltar rápidamente a una página determinada.
  • Numérico, Primera, Última además de los números de página numéricos, incluye botones para pasar a la primera página o a la última.

Para DataList y Repeater, tendrá que decidir sobre una interfaz de paginación e implementarla. Esto implica crear los controles web necesarios en la página y mostrar la página solicitada cuando se hace clic en un botón de interfaz de paginación determinado. Además, es posible que algunos controles de la interfaz de paginación se deban deshabilitar. Por ejemplo, al ver la primera página de datos con la interfaz Siguiente, Anterior, Primera, Última, se deshabilitarían los botones Primera y Última.

En este tutorial se usará la interfaz Siguiente, Anterior, Primera, Última. Agregue cuatro controles web Button a la página y establezca sus valores ID en FirstPage, PrevPage, NextPage y LastPage. Establezca las propiedades Text en << Primera, < Anterior, Siguiente >y Última>>.

<asp:Button runat="server" ID="FirstPage" Text="<< First" />
<asp:Button runat="server" ID="PrevPage" Text="< Prev" />
<asp:Button runat="server" ID="NextPage" Text="Next >" />
<asp:Button runat="server" ID="LastPage" Text="Last >>" />

A continuación, cree un controlador de eventos Click para cada uno de estos botones. En breve agregará el código necesario para mostrar la página solicitada.

Recordatorio del número total de registros paginados

Independientemente de la interfaz de paginación seleccionada, es necesario calcular y recordar el número total de registros que se paginan. El recuento total de filas (junto con el tamaño de página) determina cuántas páginas totales de datos se paginan, lo que determina qué controles de la interfaz de paginación se agregan o se habilitan. En la interfaz Siguiente, Anterior, Primera, Última que va a crear, el recuento de páginas se usa de dos maneras:

  • Para determinar si se ve la última página, en cuyo caso se deshabilitan los botones Siguiente y Última.
  • Si el usuario hace clic en el botón Última, es necesario llevarle a la última página, cuyo índice es una unidad menos que el recuento de páginas.

El recuento de páginas se calcula como el límite máximo del recuento total de filas dividido por el tamaño de página. Por ejemplo, si se paginan hasta 79 registros con 4 registros por página, el recuento de páginas es 20 (el límite máximo de 79 / 4). Si se usa la interfaz de paginación Numérica, esta información notifica el número de botones numéricos de página que se van a mostrar; si la interfaz de paginación incluye botones Siguiente o Última el recuento de páginas se usa para determinar cuándo deshabilitar los botones Siguiente o Última.

Si la interfaz de paginación incluye un botón Última, es fundamental que el número total de registros que se paginan se recuerde entre postbacks para que, al hacer clic en el botón Última, se pueda determinar el índice de la última página. Para facilitar esto, cree una propiedad TotalRowCount en la clase de código subyacente de la página ASP.NET que conserve su valor en el estado de visualización:

Private Property TotalRowCount() As Integer
    Get
        Dim o As Object = ViewState("TotalRowCount")
        If (o Is Nothing) Then
            Return -1
        Else
            Return Convert.ToInt32(o)
        End If
    End Get
    set(Value as Integer)
        ViewState("TotalRowCount") = value
    End Set
End Property

Además de TotalRowCount, dedique un minuto a crear propiedades de nivel de página de solo lectura para acceder fácilmente al índice de página, el tamaño de página y el recuento de páginas:

Private ReadOnly Property PageIndex() As Integer
    Get
        If (Not String.IsNullOrEmpty(Request.QueryString("pageIndex"))) Then
            Return Convert.ToInt32(Request.QueryString("pageIndex"))
        Else
            Return 0
        End If
    End Get
End Property
Private ReadOnly Property PageSize() As Integer
    Get
        If (Not String.IsNullOrEmpty(Request.QueryString("pageSize"))) Then
            Return Convert.ToInt32(Request.QueryString("pageSize"))
        Else
            Return 4
        End If
    End Get
End Property
Private ReadOnly Property PageCount() As Integer
    Get
        If TotalRowCount <= 0 OrElse PageSize <= 0 Then
            Return 1
        Else
            Return ((TotalRowCount + PageSize) - 1) / PageSize
        End If
    End Get
End Property

Determinación del número total de registros paginados

El objeto PagedDataSource devuelto desde el método Select() de ObjectDataSource contiene todos los registros de producto, aunque solo se muestre un subconjunto de ellos en el control DataList. La propiedadCount de PagedDataSourcesolo devuelve el número de elementos que se mostrarán en el control DataList; la propiedad DataSourceCount devuelve el número total de elementos dentro de PagedDataSource. Por tanto, es necesario asignar a la propiedad TotalRowCount de la página ASP.NET el valor de la propiedad DataSourceCount de PagedDataSource.

Para ello, cree un controlador de eventos para el evento Selected de ObjectDataSource. En el controlador de eventos Selected, tiene acceso al valor devuelto del método Select() de ObjectDataSource este caso, PagedDataSource.

Protected Sub ProductsDefaultPagingDataSource_Selected(ByVal sender As Object, _
    ByVal e As System.Web.UI.WebControls.ObjectDataSourceStatusEventArgs) _
    Handles ProductsDefaultPagingDataSource.Selected
    ' Reference the PagedDataSource bound to the DataList
    Dim pagedData As PagedDataSource = CType(e.ReturnValue, PagedDataSource)
    ' Remember the total number of records being paged through across postbacks
    TotalRowCount = pagedData.DataSourceCount
End Sub

Representación de la página de datos solicitada

Cuando el usuario hace clic en uno de los botones de la interfaz de paginación, es necesario mostrar la página de datos solicitada. Como los parámetros de paginación se especifican mediante la cadena de consulta, para mostrar la página de datos solicitada, use Response.Redirect(url) para que el explorador del usuario vuelva a solicitar la página Paging.aspx con los parámetros de paginación adecuados. Por ejemplo, para mostrar la segunda página de datos, se redirigirá al usuario a Paging.aspx?pageIndex=1.

Para facilitar esto, cree un método RedirectUser(sendUserToPageIndex) que redirija al usuario a Paging.aspx?pageIndex=sendUserToPageIndex. Después, llame a este método desde los cuatro controladores de eventos Click de Button. En el controlador de eventos FirstPageClick, llame a RedirectUser(0), para enviarlos a la primera página; en el controlador de eventos PrevPageClick, use PageIndex - 1 como índice de página, etc.

Protected Sub FirstPage_Click(ByVal sender As Object, ByVal e As EventArgs) _
    Handles FirstPage.Click
    ' Send the user to the first page
    RedirectUser(0)
End Sub
Protected Sub PrevPage_Click(ByVal sender As Object, ByVal e As EventArgs) _
    Handles PrevPage.Click
    ' Send the user to the previous page
    RedirectUser(PageIndex - 1)
End Sub
Protected Sub NextPage_Click(ByVal sender As Object, ByVal e As EventArgs) _
    Handles NextPage.Click
    ' Send the user to the next page
    RedirectUser(PageIndex + 1)
End Sub
Protected Sub LastPage_Click(ByVal sender As Object, ByVal e As EventArgs) _
    Handles LastPage.Click
    ' Send the user to the last page
    RedirectUser(PageCount - 1)
End Sub
Private Sub RedirectUser(ByVal sendUserToPageIndex As Integer)
    ' Send the user to the requested page
    Response.Redirect(String.Format("Paging.aspx?pageIndex={0}&pageSize={1}", _
        sendUserToPageIndex, PageSize))
End Sub

Con los controladores de eventos Click completados, se puede paginar por los registros de DataList al hacer clic en los botones. Tómese un momento para probarlo.

Deshabilitación de controles de la interfaz de paginación

Actualmente, los cuatro botones están habilitados independientemente de la página que se vea. Pero quiere deshabilitar los botones Primera y Anterior al mostrar la primera página de datos, y los botones Siguiente y Última al mostrar la última página. El objeto PagedDataSource devuelto por el método Select() de ObjectDataSource tiene propiedades IsFirstPage y IsLastPage que se pueden examinar para determinar si se ve la primera página de datos o la última.

Agregue lo siguiente al controlador de eventos Selected de ObjectDataSource:

' Configure the paging interface based on the data in the PagedDataSource
FirstPage.Enabled = Not pagedData.IsFirstPage
PrevPage.Enabled = Not pagedData.IsFirstPage
NextPage.Enabled = Not pagedData.IsLastPage
LastPage.Enabled = Not pagedData.IsLastPage

Con esta adición, los botones Primera y Anterior se deshabilitarán al ver la primera página, mientras que los botones Siguiente y Última se deshabilitarán al ver la última página.

Para completar la interfaz de paginación, se informará al usuario de qué página ve actualmente y cuántas páginas totales existen. Agregue un control web Label a la página y establezca su propiedad ID en CurrentPageNumber. Establezca su propiedad Text en el controlador de eventos Selected de ObjectDataSource para que incluya la página actual que se ve (PageIndex + 1) y el número total de páginas (PageCount).

' Display the current page being viewed...
CurrentPageNumber.Text = String.Format("You are viewing page {0} of {1}...", _
    PageIndex + 1, PageCount)

En la figura 10 se muestra cuándo se ha visitado Paging.aspx por primera vez. Como la cadena de consulta está vacía, de manera predeterminada el control DataList muestra los cuatro primeros productos; los botones Primero y Anterior están deshabilitados. Al hacer clic en Siguiente se muestran los cuatro registros siguientes (vea la figura 11); los botones Primero y Anterior ahora están habilitados.

The First Page of Data is Displayed

Figura 10: Se muestra la primera página de datos (Haga clic para ver la imagen a tamaño completo)

Screenshot displaying page 2 of the Paging Data in a DataList window.

Figura 11: Se muestra la segunda página de datos (Haga clic para ver la imagen a tamaño completo)

Nota:

La interfaz de paginación se puede mejorar aún más si se permite al usuario especificar cuántas páginas ver por página. Por ejemplo, se podría agregar una control DropDownList con opciones de tamaño de página como 5, 10, 25, 50 y Todo. Al seleccionar un tamaño de página, el usuario tendría que redirigirse de nuevo a Paging.aspx?pageIndex=0&pageSize=selectedPageSize. La implementación de esta mejora queda como ejercicio para el lector.

Uso de paginación personalizada

El control DataList pagina por sus datos mediante la técnica ineficaz de paginación predeterminada. Al paginar por grandes cantidades de datos, es esencial usar la paginación personalizada. Aunque los detalles de implementación difieren ligeramente, los conceptos subyacentes a la implementación de la paginación personalizada en un control DataList son los mismos que para la paginación predeterminada. Con la paginación personalizada, se usa el método GetProductsPaged de la clase ProductBLL (en lugar de GetProductsAsPagedDataSource). Como se describe en el tutorial Paginación eficaz mediante grandes cantidades de datos, a GetProductsPaged se le debe pasar el índice de fila inicial y el número máximo de filas que se van a devolver. Estos parámetros se pueden mantener con la cadena de consulta igual que los parámetros pageIndex y pageSize usados en la paginación predeterminada.

Como con la paginación personalizada no hay PagedDataSource, se deben usar técnicas alternativas para determinar el número total de registros por los que se pagina y si se muestra la primera página de datos o la última. El método TotalNumberOfProducts() de la clase ProductsBLL devuelve el número total de productos por los que se pagina. Para determinar si se ve la primera página de datos, examine el índice de fila de inicio; si es cero, se está viendo la primera página. Se ve la última página si el índice de fila inicial más las filas máximas que se van a devolver es mayor o igual que el número total de registros por los que se pagina.

La implementación de la paginación personalizada se explorará con más detalle en el siguiente tutorial.

Resumen

Aunque ni DataList ni Repeater ofrecen la compatibilidad de paginación lista para usar que se encuentra en los controles GridView, DetailsView y FormView, esta funcionalidad se puede agregar con un esfuerzo mínimo. La manera más fácil de implementar la paginación predeterminada consiste en encapsular todo el conjunto de productos dentro de una instancia de PagedDataSource y, después, enlazar PagedDataSource a DataList o Repeater. En este tutorial se ha agregado el método GetProductsAsPagedDataSource a la clase ProductsBLL para devolver PagedDataSource. La clase ProductsBLL ya contiene los métodos necesarios para la paginación personalizada de GetProductsPaged y TotalNumberOfProducts.

Junto con la recuperación del conjunto preciso de registros que se van a mostrar para la paginación personalizada o todos los registros en una instancia de PagedDataSource para la paginación predeterminada, también es necesario agregar manualmente la interfaz de paginación. En este tutorial se ha creado una interfaz Siguiente, Anterior, Primero, Último con cuatro controles web Button. Además, se ha agregado un control Label que muestra el número de página actual y el número total de páginas.

En el siguiente tutorial verá cómo agregar compatibilidad de ordenación a DataList y Repeater. También verá cómo crear un control DataList que se puede paginar y ordenar (con ejemplos mediante paginación predeterminada y personalizada).

¡Feliz programación!

Acerca del autor

Scott Mitchell, autor de siete libros de ASP/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 en mitchell@4GuysFromRolla.com. o en su blog, que se puede encontrar en http://ScottOnWriting.NET.

Agradecimientos especiales a

Muchos revisores han evaluado esta serie de tutoriales. Los revisores principales de este tutorial han sido Liz Shulok, Ken Pespisa y Bernadette Leigh. ¿Le interesa revisar mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4GuysFromRolla.com.