Paginar y ordenar datos de informes (C#)

por Scott Mitchell

Descargar PDF

La paginación y la ordenación son dos características muy comunes al mostrar datos en una aplicación en línea. En este tutorial, echaremos un primer vistazo a la adición de ordenación y paginación a nuestros informes, que después se construirán en tutoriales futuros.

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 de 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. Aunque los últimos 23 tutoriales han examinado cómo crear una variedad de informes, incluidas las interfaces que permiten agregar, editar y eliminar datos, no hemos examinado cómo ordenar datos y los únicos ejemplos de paginación que hemos visto han sido con los controles DetailsView y FormView.

En este tutorial veremos cómo agregar ordenación y paginación a nuestros informes, lo que se puede lograr simplemente marcando algunas casillas. Desafortunadamente, esta implementación simplista tiene sus inconvenientes; la interfaz de ordenación deja un poco que desear y las rutinas de paginación no están diseñadas para paginar eficazmente a través de grandes conjuntos de resultados. Los tutoriales posteriores explorarán cómo superar las limitaciones de las soluciones de paginación y ordenación listas para usar.

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

Antes de comenzar este tutorial, tomémonos un momento para agregar las páginas ASP.NET necesarias para este tutorial y los próximos tres. Empiece por crear una nueva carpeta en el proyecto denominada PagingAndSorting. 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
  • SimplePagingSorting.aspx
  • EfficientPaging.aspx
  • SortParameter.aspx
  • CustomSortingUI.aspx

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

Figura 1: Crear una carpeta PagingAndSorting y Agregar 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: Agregar el control de usuario SectionLevelTutorialListing.ascx a Default.aspx

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, Inserción y Eliminación:

<siteMapNode title="Paging and Sorting" url="~/PagingAndSorting/Default.aspx"
    description="Samples of Reports that Provide Paging and Sorting Capabilities">
    <siteMapNode url="~/PagingAndSorting/SimplePagingSorting.aspx"
        title="Simple Paging & Sorting Examples"
        description="Examines how to add simple paging and sorting support." />
    <siteMapNode url="~/PagingAndSorting/EfficientPaging.aspx"
        title="Efficiently Paging Through Large Result Sets"
        description="Learn how to efficiently page through large result sets." />
    <siteMapNode url="~/PagingAndSorting/SortParameter.aspx"
        title="Sorting Data at the BLL or DAL"
        description="Illustrates how to perform sorting logic in the Business Logic
        Layer or Data Access Layer." />
    <siteMapNode url="~/PagingAndSorting/CustomSortingUI.aspx"
        title="Customizing the Sorting User Interface"
        description="Learn how to customize and improve the sorting user interface." />
</siteMapNode>

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

Figura 3: Actualizar el mapa del sitio para incluir las nuevas páginas ASP.NET

Paso 2: Mostrar información del producto en un GridView

Antes de implementar funcionalidades de paginación y ordenación, primero vamos a crear un GridView estándar que no se pueda ordenar ni paginar y que muestre la información del producto. Esta es una tarea que hemos realizado muchas veces antes en esta serie de tutoriales, por lo que estos pasos deberían resultar familiares. Para empezar, abra la página SimplePagingSorting.aspx y arrastre un control GridView desde el Cuadro de herramientas hasta el Diseñador, estableciendo la propiedad ID en Products. A continuación, cree un objeto ObjectDataSource que use el método GetProducts() de la clase ProductsBLL para devolver toda la información del producto.

Retrieve Information About All of the Products Using the GetProducts() Method

Figura 4: Recuperar información sobre todos los productos mediante el método GetProducts()

Dado que este informe es un informe de solo lectura, no es necesario asignar los métodos Insert(), Update() o Delete() de ObjectDataSource a los métodos ProductsBLL correspondientes; por lo tanto, elija (Ninguno) en la lista desplegable para las pestañas ACTUALIZAR, INSERTAR y ELIMINAR.

Choose the (None) Option in the Drop-Down List in the UPDATE, INSERT, and DELETE Tabs

Figura 5: Elegir la opción (Ninguno) en la lista desplegable de las pestañas ACTUALIZAR, INSERTAR y ELIMINAR

A continuación, vamos a personalizar los campos de GridView para que solo se muestren los nombres de productos, proveedores, categorías, precios y estados discontinuos. Además, no dude en realizar cualquier cambio de formato a nivel de campo, como ajustar las propiedades HeaderText o dar formato al precio como moneda. Después de realizar estos cambios, el marcado declarativo de GridView debe ser similar al siguiente:

<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category"
            ReadOnly="True" SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName" HeaderText="Supplier"
            ReadOnly="True" SortExpression="SupplierName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

En la Figura 6 se muestra nuestro progreso hasta ahora cuando se ve en un explorador. Tenga en cuenta que la página enumera todos los productos en una pantalla, mostrando cada nombre, categoría, proveedor, precio y estado descontinuado del producto.

Each of the Products are Listed

Figura 6: Cada uno de los productos aparece en la lista (haga clic para ver la imagen de tamaño completo)

Paso 3: Agregar compatibilidad con la paginación

Enumerar todos los productos en una pantalla puede provocar una sobrecarga de información para el usuario que examina los datos. Para ayudar a que los resultados sean más fáciles de administrar, podemos dividir los datos en páginas más pequeñas de datos y permitir que el usuario recorra los datos una página a la vez. Para ello, simplemente active la casilla Habilitar paginación en la etiqueta inteligente de GridView (esto establece la propiedad AllowPaging de GridView entrue).

Check the Enable Paging Checkbox to Add Paging Support

Figura 7: Activar la casilla Habilitar paginación para agregar compatibilidad con la paginación (haga clic para ver la imagen de tamaño completo)

Habilitar la paginación limita el número de registros que se muestran por página y agrega una interfaz de paginación a GridView. La interfaz de paginación predeterminada, que se muestra en la Figura 7, es una serie de números de página, lo que permite al usuario navegar rápidamente de una página de datos a otra. Esta interfaz de paginación debe resultar familiar, como hemos visto al agregar compatibilidad con la paginación a los controles DetailsView y FormView en los tutoriales anteriores.

Los controles DetailsView y FormView solo muestran un único registro por página. Sin embargo, GridView consulta su propiedad PageSize para determinar cuántos registros se muestran por página (esta propiedad tiene como valor predeterminado 10).

Esta interfaz de paginación de GridView, DetailsView y FormView se puede personalizar mediante las siguientes propiedades:

  • PagerStyle indica la información de estilo de la interfaz de paginación; puede especificar valores como BackColor, ForeColor, CssClass, HorizontalAlign, etc.

  • PagerSettings contiene un grupo de propiedades que pueden personalizar la funcionalidad de la interfaz de paginación; PageButtonCount indica el número máximo de números de página numéricos mostrados en la interfaz de paginación (el valor predeterminado es 10); la propiedad Mode indica cómo funciona la interfaz de paginación y se puede establecer en:

    • NextPrevious muestra los botones Siguiente y Anterior, lo que permite al usuario avanzar o retroceder una página a la vez.
    • NextPreviousFirstLast además de los botones Siguiente y Anterior, también se incluyen los botones Primera y Última, lo que permite al usuario pasar rápidamente a la primera o última página de datos.
    • Numeric muestra una serie de números de página, lo que permite al usuario saltar inmediatamente a cualquier página.
    • NumericFirstLast además de los números de página, incluye los botones Primera y Última, lo que permite al usuario pasar rápidamente a la primera o última página de datos. Los botones Primera/Última solo se muestran si todos los números de página numéricos no caben.

Además, GridView, DetailsView y FormView ofrecen las propiedades PageIndex y PageCount, que indican la página actual que se está viendo y el número total de páginas de datos, respectivamente. La propiedad PageIndex se indexa a partir de 0, lo que significa que al ver la primera página de datos PageIndex será igual a 0. PageCount, por otro lado, comienza a contar en 1, lo que significa que PageIndex se limita a los valores entre 0 y PageCount - 1.

Dediquemos un momento a mejorar la apariencia predeterminada de nuestra interfaz de paginación de GridView. En concreto, vamos a hacer que la interfaz de paginación se alinee a la derecha con un fondo gris claro. En lugar de establecer estas propiedades directamente a través de la propiedad PagerStyle de GridView, vamos a crear una clase CSS en Styles.css denominada PagerRowStyle y, a continuación, asignaremos la propiedad CssClass de PagerStyle a través de nuestro Tema. Comience abriendo Styles.css y agregando la siguiente definición de clase CSS:

.PagerRowStyle
{
    background-color: #ddd;
    text-align: right;
}

A continuación, abra el archivo GridView.skin en la carpeta DataWebControls dentro de la carpeta App_Themes. Como se describe en el tutorial Páginas maestras y navegación del sitio, los archivos de máscara se pueden usar para especificar los valores de propiedad predeterminados para un control web. Por lo tanto, aumente la configuración existente para incluir la configuración de la propiedad CssClass de PagerStyle en PagerRowStyle. Además, vamos a configurar la interfaz de paginación para mostrar como máximo cinco botones de página numéricos mediante la interfaz de paginación NumericFirstLast.

<asp:GridView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <HeaderStyle CssClass="HeaderStyle" />
   <FooterStyle CssClass="FooterStyle" />
   <SelectedRowStyle CssClass="SelectedRowStyle" />
   <PagerStyle CssClass="PagerRowStyle" />
   <PagerSettings Mode="NumericFirstLast" PageButtonCount="5" />
</asp:GridView>

Experiencia del usuario de paginación

En la Figura 8 se muestra la página web cuando se visita a través de un explorador después de activar la casilla Habilitar paginación de GridView y de haber realizado las configuraciones PagerStyle y PagerSettings a través del archivo GridView.skin. Observe como solo se muestran diez registros y la interfaz de paginación indica que estamos viendo la primera página de datos.

With Paging Enabled, Only a Subset of the Records are Displayed at a Time

Figura 8: Con la paginación habilitada, solo se muestra un subconjunto de los registros a la vez (haga clic para ver la imagen de tamaño completo)

Cuando el usuario hace clic en uno de los números de página de la interfaz de paginación, se produce un postback y la página se vuelve a cargar mostrando los registros de la página solicitada. En la Figura 9 se muestran los resultados después de optar por ver la página final de datos. Observe que la página final solo tiene un registro; esto se debe a que hay 81 registros en total, lo que da como resultado 8 páginas de 10 registros por página más una página con un único registro.

Clicking On a Page Number Causes a Postback and Shows the Appropriate Subset of Records

Figura 9: Al hacer clic en un número de página, se produce un postback y se muestra el subconjunto adecuado de registros (haga clic para ver la imagen de tamaño completo)

Flujo de trabajo del lado servidor de paginación

Cuando el usuario final hace clic en un botón de la interfaz de paginación, se produce un postback y comienza el siguiente flujo de trabajo del lado servidor:

  1. Se desencadena el evento PageIndexChanging de GridView (o DetailsView o FormView)
  2. ObjectDataSource vuelve a solicitar todos los datos de la BLL; los valores de propiedad PageIndex y PageSize de GridView se usan para determinar qué registros devueltos de la BLL deben mostrarse en GridView.
  3. Se desencadena el evento PageIndexChanged de GridView

En el paso 2, ObjectDataSource vuelve a solicitar todos los datos de su origen de datos. Este estilo de paginación se conoce normalmente como paginación predeterminada, ya que es el comportamiento de paginación usado de manera predeterminada al establecer la propiedad AllowPaging en true. Con la paginación predeterminada, el control web de datos recupera de forma nativa todos los registros de cada página de datos, aunque solo un subconjunto de registros se represente realmente en el HTML que se envía al explorador. A menos que la BLL u ObjectDataSource almacenen en caché los datos de la base de datos, la paginación predeterminada es inviable para conjuntos de resultados lo suficientemente grandes o para aplicaciones web con muchos usuarios simultáneos.

En el siguiente tutorial, examinaremos cómo implementar la paginación personalizada. Con la paginación personalizada, puede indicar específicamente a ObjectDataSource que solo recupere el conjunto preciso de registros necesarios para la página de datos solicitada. Como puede imaginar, la paginación personalizada mejora considerablemente la eficacia de la paginación a través de grandes conjuntos de resultados.

Nota:

Aunque la paginación predeterminada no es adecuada al paginar a través de conjuntos de resultados suficientemente grandes o para sitios con muchos usuarios simultáneos, tenga en cuenta que la paginación personalizada requiere más cambios y un mayor esfuerzo para implementarse y no es tan simple como marcar una casilla (como es la paginación predeterminada). Por lo tanto, la paginación predeterminada puede ser la opción ideal para sitios web pequeños y con poco tráfico o al paginar a través de conjuntos de resultados relativamente pequeños, ya que es mucho más fácil y rápida de implementar.

Por ejemplo, si sabemos que nunca tendremos más de 100 productos en nuestra base de datos, es probable que el esfuerzo necesario para implementarla contrarreste al rendimiento mínimo logrado con la paginación personalizada. Sin embargo, si es posible que un día tengamos miles o decenas de miles de productos, no implementar la paginación personalizada dificultaría considerablemente la escalabilidad de nuestra aplicación.

Paso 4: Personalizar la experiencia de paginación

Los controles web de datos proporcionan una serie de propiedades que se pueden usar para mejorar la experiencia de paginación del usuario. La propiedad PageCount, por ejemplo, indica cuántas páginas totales hay, mientras que la propiedad PageIndex indica la página actual que se está visitando y se puede establecer para mover rápidamente un usuario a una página específica. Para ilustrar cómo usar estas propiedades para mejorar la experiencia de paginación del usuario, vamos a agregar un control web Label a nuestra página que informe al usuario sobre qué página está visitando actualmente, junto con un control DropDownList que le permita saltar rápidamente a cualquier página determinada.

En primer lugar, agregue un control web Label a la página, establezca la propiedad ID en PagingInformation y borre la propiedad Text. A continuación, cree un controlador de eventos para el evento DataBound de GridView y agregue el código siguiente:

protected void Products_DataBound(object sender, EventArgs e)
{
    PagingInformation.Text = string.Format("You are viewing page {0} of {1}...",
        Products.PageIndex + 1, Products.PageCount);
}

Este controlador de eventos asigna la propiedad Text de Label de PagingInformation a un mensaje que informa al usuario sobre la página que está visitando actualmente Products.PageIndex + 1 de cuántas páginas totales Products.PageCount (agregamos 1 a la propiedad Products.PageIndex porque PageIndex se indexa a partir de 0). Elegí la asignación de esta propiedad Text de Label en el controlador de eventos DataBound en lugar del controlador de eventos PageIndexChanged porque el evento DataBound se desencadena cada vez que los datos están enlazados a GridView, mientras que el controlador de eventos PageIndexChanged solo se activa cuando se cambia el índice de página. Cuando GridView está inicialmente enlazado a datos en la primera visita a la página, el evento PageIndexChanging no se desencadena (mientras que el evento DataBound sí).

Con esta adición, el usuario ahora ve un mensaje que indica qué página está visitando y cuántas páginas totales de datos hay.

The Current Page Number and Total Number of Pages are Displayed

Figura 10: Se muestran el número de página actual y el número total de páginas (haga clic para ver la imagen de tamaño completo)

Además del control Label, vamos a agregar también un control DropDownList que enumera los números de página en GridView con la página actualmente vista seleccionada. La idea aquí es que el usuario pueda saltar rápidamente de la página actual a otra simplemente seleccionando el nuevo índice de página en DropDownList. Empiece agregando un DropDownList al Diseñador, estableciendo la propiedad ID en PageList y comprobando la opción Habilitar AutoPostBack desde la etiqueta inteligente.

A continuación, vuelva al controlador de eventos DataBound y agregue el código siguiente:

// Clear out all of the items in the DropDownList
PageList.Items.Clear();
// Add a ListItem for each page
for (int i = 0; i < Products.PageCount; i++)
{
    // Add the new ListItem
    ListItem pageListItem = new ListItem(string.Concat("Page ", i + 1), i.ToString());
    PageList.Items.Add(pageListItem);
    // select the current item, if needed
    if (i == Products.PageIndex)
        pageListItem.Selected = true;
}

Este código comienza borrando los elementos de DropDownList PageList. Esto puede parecer superfluo, ya que uno no esperaría que cambie el número de páginas, pero otros usuarios pueden estar usando el sistema simultáneamente, agregando o quitando registros de la tabla Products. Estas inserciones o eliminaciones podrían modificar el número de páginas de datos.

A continuación, es necesario volver a crear los números de página y seleccionar de manera predeterminada la página que se asigna a PageIndex del GridView actual. Esto se logra con un bucle de 0 a PageCount - 1, agregando un nuevo ListItem en cada iteración y estableciendo la propiedad Selected en true si el índice de iteración actual es igual a la propiedad PageIndex de GridView.

Por último, es necesario crear un controlador de eventos para el evento SelectedIndexChanged de DropDownList, que se activa cada vez que el usuario elige un elemento diferente de la lista. Para crear este controlador de eventos, simplemente haga doble clic en DropDownList en el Diseñador y agregue el código siguiente:

protected void PageList_SelectedIndexChanged(object sender, EventArgs e)
{
    // Jump to the specified page
    Products.PageIndex = Convert.ToInt32(PageList.SelectedValue);
}

Como se muestra en la Figura 11, simplemente cambiar la propiedad PageIndex de GridView hace que los datos se vuelvan a enlazar a GridView. En el controlador de eventos DataBound de GridView, se selecciona el ListItem de DropDownList adecuado.

The User is Automatically Taken to the Sixth Page When Selecting the Page 6 Drop-Down List Item

Figura 11: El usuario es llevado automáticamente a la sexta página al seleccionar el elemento Página 6 de la lista desplegable (haga clic para ver la imagen de tamaño completo)

Paso 5: Agregar compatibilidad con la ordenación bidireccional

Agregar compatibilidad con la ordenación bidireccional es tan simple como agregar compatibilidad con la paginación; simplemente habilite la opción Habilitar ordenación de la etiqueta inteligente de GridView (que establece la propiedad AllowSorting de GridView en true). Esto representa cada uno de los encabezados de los campos de GridView como LinkButtons que, cuando se hace clic en ellos, provocan un postback y devuelven los datos ordenados de acuerdo con la columna en que se hizo clic en orden ascendente. Al hacer clic en el mismo encabezado LinkButton, se vuelven a ordenar los datos en orden descendente.

Nota:

Si usa una capa de acceso a datos personalizada en lugar de un conjunto de datos con tipo, es posible que no tenga la opción Habilitar ordenación en la etiqueta inteligente de GridView. Solo los GridViews enlazados a orígenes de datos que admiten la ordenación de forma nativa tienen esta casilla disponible. El conjunto de datos con tipo proporciona compatibilidad de ordenación lista para usar, ya que la DataTable de ADO.NET proporciona un método Sort que, cuando se invoca, ordena las DataRows de DataTable mediante los criterios especificados.

Si el DAL no devuelve los objetos que admiten de forma nativa la ordenación, deberá configurar ObjectDataSource para pasar la información de ordenación a la capa lógica de negocios, que puede ordenar los datos o hacer que DAL ordene los datos. Exploraremos cómo ordenar los datos en las capas de lógica de negocios y acceso a datos en un tutorial posterior.

Los LinkButtons de ordenación se representan como hipervínculos HTML, cuyos colores actuales (azul para un vínculo no visitado y rojo oscuro para un vínculo visitado) entran en conflicto con el color de fondo de la fila de encabezado. En su lugar, hagamos que todos los vínculos de fila de encabezado se muestren en blanco, independientemente de si se han visitado o no. Esto se puede lograr agregando lo siguiente a la clase Styles.css:

.HeaderStyle a, .HeaderStyle a:visited
{
    color: White;
}

Esta sintaxis indica que se use texto blanco al mostrar esos hipervínculos dentro de un elemento que usa la clase HeaderStyle.

Después de esta adición de CSS, al visitar la página a través de un explorador, la pantalla debe lucir similar a la Figura 12. En concreto, la Figura 12 muestra los resultados después de hacer clic en el vínculo de encabezado del campo Precio.

Screenshot of the Simple Paging & Sorting window showing the results sorted by the Price column in ascending order.

Figura 12: Los resultados se han ordenado por UnitPrice en orden ascendente (haga clic para ver la imagen de tamaño completo)

Examen del flujo de trabajo de ordenación

Todos los campos de GridView BoundField, CheckBoxField, TemplateField, etc. tienen una propiedad SortExpression que indica la expresión que se debe usar para ordenar los datos cuando se hace clic en el vínculo de encabezado de ordenación de ese campo. GridView también tiene una propiedad SortExpression. Cuando se hace clic en un LinkButton de encabezado de ordenación, GridView asigna ese valor SortExpression del campo a la propiedad SortExpression. A continuación, los datos se vuelven a recuperar de ObjectDataSource y se ordenan según la propiedad SortExpression de GridView. En la lista siguiente se detalla la secuencia de pasos que tienen lugar cuando un usuario final ordena los datos en GridView:

  1. Se desencadena el evento de ordenación de GridView
  2. La propiedad SortExpression de GridView se establece en SortExpression del campo donde se hizo clic en el LinkButton de encabezado de ordenación.
  3. ObjectDataSource vuelve a recuperar todos los datos de la BLL y, a continuación, ordena los datos mediante SortExpression de GridView.
  4. La propiedad PageIndex de GridView se restablece en 0, lo que significa que al ordenar el usuario vuelve a la primera página de datos (suponiendo que se ha implementado la compatibilidad de paginación)
  5. Se desencadena el evento Sorted de GridView

Al igual que con la paginación predeterminada, la opción de ordenación predeterminada vuelve a recuperar todos los registros de la BLL. Cuando se usa la ordenación sin paginación o cuando se usa la ordenación con la paginación predeterminada, no hay ninguna manera de eludir este impacto en el rendimiento (falta de almacenamiento en caché de los datos de la base de datos). Sin embargo, como veremos en un tutorial posterior, es posible ordenar de forma eficaz los datos al usar la paginación personalizada.

Al enlazar un ObjectDataSource a GridView a través de la lista desplegable de la etiqueta inteligente de GridView, cada campo de GridView tiene automáticamente la propiedad SortExpression asignada al nombre del campo de datos de la clase ProductsRow. Por ejemplo, SortExpression de BoundField de ProductName se establece en ProductName, como se muestra en el siguiente marcado declarativo:

<asp:BoundField DataField="ProductName" HeaderText="Product"
    SortExpression="ProductName" />

Se puede configurar un campo para que no se pueda ordenar borrando su propiedad SortExpression (asignarlo a una cadena vacía). Para ilustrar esto, imagine que no queríamos permitir a nuestros clientes ordenar nuestros productos por precio. La propiedad SortExpression de BoundField de UnitPrice se puede quitar del marcado declarativo o a través del cuadro de diálogo Campos (al que se puede acceder haciendo clic en el vínculo Editar columnas de la etiqueta inteligente de GridView).

Screenshot of the Fields window with Price and SortExpression highlighted.

Figura 13: Los resultados se han ordenado por UnitPrice en orden ascendente

Una vez que se ha quitado la propiedad SortExpression para BoundField UnitPrice, el encabezado se representa como texto en lugar de como un vínculo, lo que impide que los usuarios ordenen los datos por precio.

By Removing the SortExpression Property, Users Can No Longer Sort the Products By Price

Figura 14: Al quitar la propiedad SortExpression, los usuarios ya no pueden ordenar los productos por precio (haga clic para ver la imagen de tamaño completo)

Ordenación mediante programación de GridView

También puede ordenar el contenido de GridView mediante programación mediante el método Sort de GridView. Simplemente pase el valor SortExpression para ordenarlo junto con los SortDirection (Ascending o Descending) y los datos de GridView se volverán a ordenar.

Imagine que la razón por la que desactivemos la ordenación por UnitPrice era porque nos preocupaba que nuestros clientes simplemente compraran solo los productos de menor precio. Sin embargo, queremos animarlos a comprar los productos más caros, por lo que nos gustaría que pudieran ordenar los productos por precio, pero solo del precio más caro al más barato.

Para ello, agregue un control web Button a la página, establezca la propiedad ID en SortPriceDescending y la propiedad Text en Ordenar por precio. A continuación, cree un controlador de eventos para el evento Click de Button haciendo doble clic en el control Button en el Diseñador. Agregue el código siguiente a este controlador de eventos:

protected void SortPriceDescending_Click(object sender, EventArgs e)
{
    // Sort by UnitPrice in descending order
    Products.Sort("UnitPrice", SortDirection.Descending);
}

Al hacer clic en este botón, el usuario vuelve a la primera página con los productos ordenados por precio, del más caro al más barato (consulte la figura 15).

Clicking the Button Orders the Products From the Most Expensive to the Least

Figura 15: Hacer clic en el botón ordena los productos del más caro al más barato (hacer clic para ver la imagen de tamaño completo)

Resumen

En este tutorial hemos visto cómo implementar funcionalidades de paginación y ordenación predeterminadas, y ambas eran tan fáciles como habilitar una casilla. Cuando un usuario ordena o pagina a través de datos, se desarrolla un flujo de trabajo similar:

  1. Se produce un postback
  2. Se desencadena el evento de nivel previo del control web de datos (PageIndexChanging o Sorting)
  3. ObjectDataSource vuelve a recuperar todos los datos
  4. Se desencadena el evento de nivel posterior del control web de datos (PageIndexChanged o Sorted)

Aunque la implementación básica de paginación y ordenación es muy sencilla, se debe ejercer un mayor esfuerzo para utilizar la paginación personalizada más eficaz o para mejorar aún más la interfaz de paginación u ordenación. Los tutoriales posteriores explorarán estos temas.

¡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 a través de mitchell@4GuysFromRolla.com. o a través de su blog, que se puede encontrar en http://ScottOnWriting.NET.