Crear una interfaz para seleccionar una cuenta de usuario entre varias cuentas (C#)

por Scott Mitchell

En este tutorial crearemos una interfaz de usuario con una cuadrícula paginada y filtrable. En concreto, nuestra interfaz de usuario constará de una serie de LinkButtons para filtrar los resultados en función de la letra inicial del nombre de usuario y un control de GridView para mostrar los usuarios coincidentes. Comenzaremos enumerando todas las cuentas de usuario en GridView. A continuación, en el paso 3, agregaremos el filtro LinkButtons. El paso 4 examina la paginación de los resultados filtrados. La interfaz construida en los pasos 2 a 4 se usará en los tutoriales posteriores para realizar tareas administrativas para una cuenta de usuario determinada.

Introducción

En el tutorial Asignación de roles a usuarios, creamos una interfaz rudimentaria para que un administrador seleccione un usuario y administre sus roles. En concreto, la interfaz presentó al administrador una lista desplegable de todos los usuarios. Esta interfaz es adecuada cuando hay una docena de cuentas de usuario, pero resulta poco manejable para sitios con cientos o miles de cuentas. Una cuadrícula paginada y filtrable es una interfaz de usuario más adecuada para sitios web con bases de usuarios grandes.

En este tutorial crearemos una interfaz de usuario de este tipo. En concreto, nuestra interfaz de usuario constará de una serie de LinkButtons para filtrar los resultados en función de la letra inicial del nombre de usuario y un control de GridView para mostrar los usuarios coincidentes. Comenzaremos enumerando todas las cuentas de usuario en una GridView. A continuación, en el paso 3, agregaremos el filtro de LinkButtons. El paso 4 examina la paginación de los resultados filtrados. La interfaz construida en los pasos 2 a 4 se usará en los tutoriales posteriores para realizar tareas administrativas para una cuenta de usuario determinada.

Comencemos.

Paso 1: Agregar nuevas páginas de ASP.NET

En este tutorial y en los dos siguientes examinaremos varias funciones y funcionalidades relacionadas con la administración. Necesitaremos una serie de páginas de ASP.NET para implementar los temas examinados en estos tutoriales. Vamos a crear estas páginas y actualizar el mapa del sitio.

Empiece por crear una nueva carpeta en el proyecto denominada Administration. A continuación, agregue dos nuevas páginas de ASP.NET a la carpeta y vincule cada página con la página maestra Site.master. Asigne un nombre a las páginas:

  • ManageUsers.aspx
  • UserInformation.aspx

Agregue también dos páginas al directorio raíz del sitio web: ChangePassword.aspx y RecoverPassword.aspx.

Estas cuatro páginas deben, en este momento, tener dos controles de contenido, uno para cada uno de los ContentPlaceHolders de la página maestra: MainContent y LoginContent.

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="LoginContent" Runat="Server">
</asp:Content>

Queremos mostrar el marcado predeterminado de la página maestra para el ContentPlaceHolder LoginContent para estas páginas. Por lo tanto, quite el marcado declarativo del control de contenido Content2. Después de hacerlo, el marcado de las páginas debe contener solo un control de contenido.

Las páginas de ASP.NET de la carpeta Administration están pensadas únicamente para usuarios administrativos. Hemos agregado un rol Administradores al sistema en el tutorial Creación y administración de roles; restrinja el acceso a estas dos páginas para este rol. Para ello, agregue un archivo Web.config a la carpeta Administration y configure su elemento <authorization> para admitir usuarios en el rol Administradores y denegar a todos los demás.

<?xml version="1.0"?>
<configuration>
 <system.web>
 <authorization>
 <allow roles="Administrators" />
 <deny users="*"/>
 </authorization>
 </system.web>
</configuration>

En este momento, el Explorador de soluciones del proyecto debe ser similar a la captura de pantalla que se muestra en la figura 1.

Four New Pages and a Web.config File Have Been Added to the Website

Figura 1: Se han agregado cuatro páginas nuevas y un archivo Web.config al sitio web (Haga clic para ver la imagen a tamaño completo)

Por último, actualice el mapa del sitio (Web.sitemap) para incluir una entrada a la página ManageUsers.aspx. Agregue el siguiente XML después de la <siteMapNode> que hemos agregado para los tutoriales de roles.

<siteMapNode title="User Administration" url="~/Administration/ManageUsers.aspx"/>

Con el mapa del sitio actualizado, visite el sitio a través de un explorador. Como se muestra en la Figura 2, la navegación de la izquierda ahora incluye elementos para los tutoriales de administración.

The Site Map Includes a Node Titled User Administration

Figura 2: El mapa del sitio incluye un nodo titulado Administración de usuarios (Haga clic para ver la imagen a tamaño completo)

Paso 2: Enumerar todas las cuentas de usuario en GridView

Nuestro objetivo final para este tutorial es crear una cuadrícula paginada filtrable a través de la cual un administrador puede seleccionar una cuenta de usuario para administrar. Comencemos por enumerar todos los usuarios de una GridView. Una vez completado esto, agregaremos las interfaces y funcionalidades de filtrado y paginación.

Abra la página ManageUsers.aspx en la carpeta Administration y agregue una GridView, estableciendo su ID en UserAccounts. En un momento, escribiremos código para enlazar el conjunto de cuentas de usuario a la GridView mediante la clase Membership y el método GetAllUsers. Como se explicó en los tutoriales anteriores, el método GetAllUsers devuelve un objeto MembershipUserCollection, que es una colección de objetos MembershipUser. Cada MembershipUser en las colecciones incluye propiedades como UserName, Email, IsApproved, etc.

Para mostrar la información de la cuenta de usuario deseada en la GridView, establezca la propiedad AutoGenerateColumns de GridView en False y agregue BoundFields para las propiedades UserName, Email y Comment, y CheckBoxFields para las propiedades IsApproved, IsLockedOut y IsOnline. Esta configuración se puede aplicar a través del marcado declarativo del control o mediante el cuadro de diálogo Campos. En la Figura 3 se muestra una captura de pantalla del cuadro de diálogo Campos después de que se desactive la casilla Generar campos automáticamente y se hayan agregado y configurado los BoundFields y CheckBoxFields.

Add Three BoundFields and Three CheckBoxFields to the GridView

Figura 3: Agregar tres BoundFields y tres CheckBoxFields a la GridView (Haga clic para ver la imagen de tamaño completo)

Después de configurar GridView, asegúrese de que su marcado declarativo es similar al siguiente:

<asp:GridView ID="UserAccounts" runat="server" AutoGenerateColumns="False">
 <Columns>
 <asp:BoundField DataField="UserName" HeaderText="UserName"/>
 <asp:BoundField DataField="Email" HeaderText="Email" />
 <asp:CheckBoxField DataField="IsApproved" HeaderText="Approved?"/>
 <asp:CheckBoxField DataField="IsLockedOut" HeaderText="Locked Out?" />
 <asp:CheckBoxField DataField="IsOnline" HeaderText="Online?"/>
 <asp:BoundField DataField="Comment" HeaderText="Comment"/>
 </Columns>
</asp:GridView>

A continuación, es necesario escribir código que enlace las cuentas de usuario a la GridView. Cree un método denominado BindUserAccounts para realizar esta tarea y, a continuación, llámelo desde el controlador de eventos Page_Load en la primera visita de página.

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    BindUserAccounts();
}

private void BindUserAccounts()
{
    UserAccounts.DataSource = Membership.GetAllUsers();
    UserAccounts.DataBind();
}

Dedique un momento a probar la página a través de un explorador. Como se muestra en la Figura 4, la GridView UserAccounts enumera el nombre de usuario, la dirección de correo electrónico y otra información de cuenta pertinente para todos los usuarios del sistema.

The User Accounts are Listed in the GridView

Figura 4: Las cuentas de usuario se muestran en la GridView (Haga clic para ver la imagen a tamaño completo)

Paso 3: Filtrar los resultados por la primera letra del nombre de usuario

Actualmente, la GridView UserAccounts muestra todas las cuentas de usuario. Para sitios web con cientos o miles de cuentas de usuario, es imperativo que el usuario pueda establecer rápidamente las cuentas mostradas. Esto se puede lograr agregando filtros de LinkButtons a la página. Vamos a agregar 27 LinkButtons a la página: uno titulado All junto con un LinkButton para cada letra del alfabeto. Si un visitante hace clic en el LinkButton All, la GridView mostrará todos los usuarios. Si hacen clic en una letra determinada, solo se mostrarán los usuarios cuyo nombre de usuario comienza con la letra seleccionada.

Nuestra primera tarea es agregar los 27 controles de LinkButton. Una opción sería crear los 27 LinkButtons mediante declaración, de uno en uno. Un enfoque más flexible es usar un control Repeater con un ItemTemplate que representa un LinkButton y, a continuación, enlaza las opciones de filtrado al Repeater como una matriz de string.

Empiece agregando un control Repeater a la página situada encima de la GridView UserAccounts. Establezca la propiedad ID de Repeater en FilteringUI. Configure las plantillas del Repeater para que ItemTemplate represente un LinkButton cuyas propiedades Text y CommandName están enlazadas al elemento de matriz actual. Como vimos en el tutorial Asignación de roles a usuarios, esto se puede lograr mediante la sintaxis de enlace de datos Container.DataItem. Use SeparatorTemplate de Repeater para mostrar una línea vertical entre cada vínculo.

<asp:Repeater ID="FilteringUI" runat="server">
 <ItemTemplate>
 <asp:LinkButton runat="server" ID="lnkFilter"
 Text='<%# Container.DataItem %>'
 CommandName='<%# Container.DataItem %>'></asp:LinkButton>
 </ItemTemplate>
 <SeparatorTemplate>|</SeparatorTemplate>
</asp:Repeater>

Para rellenar este Repeater con las opciones de filtrado deseadas, cree un método denominado BindFilteringUI. Asegúrese de llamar a este método desde el controlador de eventos Page_Load en la primera carga de página.

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        BindUserAccounts();
        BindFilteringUI();
    }
}

private void BindFilteringUI()
{
    string[] filterOptions = { "All", "A", "B", "C","D", "E", "F", "G", "H", "I","J", "K", "L", "M", "N", "O","P", "Q", "R", "S", "T", "U","V", "W", "X", "Y", "Z" };
    FilteringUI.DataSource = filterOptions;
    FilteringUI.DataBind();
}

Este método especifica las opciones de filtrado como elementos de la matriz de stringfilterOptions. Para cada elemento de la matriz, el Repeater representará un LinkButton con sus propiedades Text y CommandName asignadas al valor del elemento de matriz.

En la Figura 5 se muestra la página ManageUsers.aspx cuando se ve a través de un explorador.

The Repeater Lists 27 Filtering LinkButtons

Figura 5: El Repeater enumera 27 LinkButtons de filtrado (Haga clic para ver la imagen a tamaño completo)

Nota:

Los nombres de usuario pueden comenzar con cualquier carácter, incluidos números y puntuación. Para ver estas cuentas, el administrador tendrá que usar la opción All de LinkButton. Como alternativa, puede agregar un LinkButton para devolver todas las cuentas de usuario que comienzan por un número. Lo dejo como ejercicio para el lector.

Al hacer clic en cualquiera de los LinkButtons de filtrado, se produce un postback y se genera el evento ItemCommand del Repeater, pero no hay ningún cambio en la cuadrícula porque todavía tenemos que escribir código para filtrar los resultados. La clase Membership incluye un método FindUsersByName que devuelve esas cuentas de usuario cuyo nombre de usuario coincide con un patrón de búsqueda especificado. Podemos usar este método para recuperar solo las cuentas de usuario cuyos nombres de usuario comienzan con la letra especificada por el CommandName del LinkButton de filtrado en el que se hizo clic.

Empiece por actualizar la clase de código subyacente de la página ManageUser.aspx para que incluya una propiedad denominada UsernameToMatch. Esta propiedad conserva la cadena de filtro de nombre de usuario entre postbacks:

private string UsernameToMatch
{
 get
 {
 object o = ViewState["UsernameToMatch"];
 if (o == null)
 return string.Empty;
 else
 return (string)o;
 }
 set
 {
 ViewState["UsernameToMatch"] = value;
 }
}

La propiedad UsernameToMatch almacena su valor asignado en la colección ViewState mediante la clave UsernameToMatch. Cuando se lee este valor de propiedad, se comprueba si existe un valor en la colección ViewState; si no es así, devuelve el valor predeterminado, una cadena vacía. La propiedad UsernameToMatch muestra un patrón común, es decir, la persistencia de un valor en el estado de visualización para que los cambios realizados en la propiedad se conserven entre postbacks. Para obtener más información sobre este patrón, lea Descripción del estado de visualización de ASP.NET.

A continuación, actualice el método BindUserAccounts para que, en lugar de llamar a Membership.GetAllUsers, llame a Membership.FindUsersByNamey pase el valor de la propiedad UsernameToMatch anexado con el carácter comodín de SQL, %.

private void BindUserAccounts()
{
    UserAccounts.DataSource = Membership.FindUsersByName(this.UsernameToMatch + "%");
    UserAccounts.DataBind();
}

Para mostrar solo los usuarios cuyo nombre de usuario comienza con la letra A, establezca la propiedad UsernameToMatch en A y, a continuación, llame a BindUserAccounts. Esto daría lugar a una llamada a Membership.FindUsersByName("A%"), que devolverá todos los usuarios cuyo nombre de usuario comienza con A. Del mismo modo, para devolver todos los usuarios, asigne una cadena vacía a la propiedad UsernameToMatch para que el método BindUserAccounts invoque Membership.FindUsersByName("%"), devolviendo así todas las cuentas de usuario.

Cree un controlador de eventos para el evento ItemCommand del Repeater. Este evento se genera cada vez que se hace clic en uno de los filtros de LinkButtons; se pasa el valor CommandName del LinkButton al que se hace clic a través del objeto RepeaterCommandEventArgs. Es necesario asignar el valor adecuado a la propiedad UsernameToMatch y, a continuación, llamar al método BindUserAccounts. Si CommandName es All, asigne una cadena vacía a UsernameToMatch para que se muestren todas las cuentas de usuario. De lo contrario, asigne el valor CommandName a UsernameToMatch.

protected void FilteringUI_ItemCommand(object source, RepeaterCommandEventArgs e)
{
    if (e.CommandName == "All")
        this.UsernameToMatch = string.Empty;
    else
        this.UsernameToMatch e.CommandName;
    BindUserAccounts();
}

Con este código implementado, pruebe la funcionalidad de filtrado. Cuando se visita la página por primera vez, se muestran todas las cuentas de usuario (consulte la Figura 5). Al hacer clic en el LinkButton A, se produce un postback y se filtran los resultados, mostrando solo las cuentas de usuario que comienzan por A.

Use the Filtering LinkButtons to Display those Users Whose Username Starts with a Certain Letter

Figura 6: Usar los LinkButtons de filtrado para mostrar los usuarios cuyo nombre de usuario comienza con una letra determinada (Haga clic para ver la imagen a tamaño completo)

Paso 4: Actualizar la GridView para usar la paginación

La GridView que se muestra en las Figuras 5 y 6 enumera todos los registros devueltos por el método FindUsersByName. Si hay cientos o miles de cuentas de usuario, esto puede provocar una sobrecarga de información al ver todas las cuentas (como sucede cuando se hace clic en el botón All de LinkButton o al visitar inicialmente la página). Para ayudar a presentar las cuentas de usuario en fragmentos más fáciles de administrar, vamos a configurar la GridView para mostrar 10 cuentas de usuario a la vez.

El control de GridView ofrece dos tipos de paginación:

  • Paginación predeterminada: fácil de implementar, pero ineficaz. En pocas palabras, con la paginación predeterminada, la GridView espera todos los registros de su origen de datos. A continuación, solo muestra la página adecuada de registros.
  • Paginación personalizada: requiere más trabajo para implementar, pero es más eficaz que la paginación predeterminada porque, con la paginación personalizada, el origen de datos devuelve solo el conjunto preciso de registros que se va a mostrar.

La diferencia de rendimiento entre la paginación predeterminada y personalizada puede ser bastante sustancial al paginar a través de miles de registros. Dado que estamos creando esta interfaz suponiendo que puede haber cientos o miles de cuentas de usuario, vamos a usar la paginación personalizada.

Nota:

Para obtener una explicación más exhaustiva sobre las diferencias entre la paginación predeterminada y personalizada, así como los desafíos implicados en la implementación de la paginación personalizada, consulte Paginación eficaz a través de grandes cantidades de datos.

Para implementar la paginación personalizada, primero necesitamos algún mecanismo para recuperar el subconjunto preciso de registros que muestra la GridView. La buena noticia es que la clase Membership, método FindUsersByName, tiene una sobrecarga que nos permite especificar el índice de página y el tamaño de página, y devuelve solo las cuentas de usuario que se encuentran dentro de ese intervalo de registros.

En concreto, esta sobrecarga tiene la siguiente firma: FindUsersByName(usernameToMatch, pageIndex, pageSize, totalRecords).

El parámetro pageIndex especifica la página de cuentas de usuario que se van a devolver; mientras que pageSize indica cuántos registros se van a mostrar por página. El parámetro totalRecords es un parámetro out que devuelve el número de cuentas de usuario totales en el almacén de usuarios.

Nota:

Los datos devueltos por FindUsersByName se ordenan por nombre de usuario; no se pueden personalizar los criterios de ordenación.

La GridView se puede configurar para usar la paginación personalizada, pero solo cuando se enlaza a un control de ObjectDataSource. Para que el control de ObjectDataSource implemente la paginación personalizada, requiere dos métodos: uno que se pasa a un índice de fila de inicio y el número máximo de registros que se van a mostrar y devuelve el subconjunto preciso de registros que se encuentran dentro de ese intervalo; y un método que devuelve el número total de registros que se paginan. La sobrecarga FindUsersByName acepta un índice de página y un tamaño de página, y devuelve el número total de registros a través de un parámetro out. Por lo tanto, aquí hay una falta de coincidencia de interfaz.

Una opción sería crear una clase de proxy que expone la interfaz que espera ObjectDataSource y, a continuación, llama internamente al método FindUsersByName. Otra opción, y la que usaremos para este artículo, es crear nuestra propia interfaz de paginación y usarla en lugar de la interfaz de paginación integrada de la GridView.

Creación de una interfaz de paginación Primera, Anterior, Siguiente, Última

Vamos a crear una interfaz de paginación con los LinkButtons Primera, Anterior, Siguiente y Última. El LinkButton Primera, cuando se haga clic, llevará al usuario a la primera página de datos, mientras que Anterior lo devolverá a la página anterior. Del mismo modo, Siguiente y Última moverán al usuario a la página siguiente y última, respectivamente. Agregue los cuatro controles LinkButton debajo de la GridView UserAccounts.

<p>
 <asp:LinkButton ID="lnkFirst" runat="server"> First</asp:LinkButton> |
 <asp:LinkButton ID="lnkPrev" runat="server">  Prev</asp:LinkButton>|
 <asp:LinkButton ID="lnkNext" runat="server">Next  </asp:LinkButton>|
 <asp:LinkButton ID="lnkLast" runat="server">Last  </asp:LinkButton>
</p>

A continuación, cree un controlador de eventos para cada uno de los eventos de Click del LinkButton.

En la Figura 7 se muestran los cuatro LinkButtons cuando se ven a través de la Vista de diseño del desarrollador web visual.

Add First, Previous, Next, and Last LinkButtons Beneath the GridView

Figura 7: Agregar los LinkButtons Primera, Anterior, Siguiente y Última debajo de la GridView (Haga clic para ver la imagen a tamaño completo)

Seguimiento del índice de página actual

Cuando un usuario visita por primera vez la página ManageUsers.aspx o hace clic en uno de los botones de filtrado, queremos mostrar la primera página de datos en la GridView. Sin embargo, cuando el usuario hace clic en uno de los LinkButtons de navegación, es necesario actualizar el índice de página. Para mantener el índice de página y el número de registros que se van a mostrar por página, agregue las dos propiedades siguientes a la clase de código subyacente de la página:

private int PageIndex
{
 get
 {
 object o = ViewState["PageIndex"];
 if (o == null)
 return 0;
 else
 return (int)o;
 }
 set
 {
 ViewState["PageIndex"] = value;
 }
}

private int PageSize
{
 get
 {
 return 10;
 }
}

Al igual que la propiedad UsernameToMatch, la propiedad PageIndex conserva su valor para el estado de visualización. La propiedad PageSize de solo lectura devuelve un valor codificado de forma rígida, 10. Invite al lector interesado a actualizar esta propiedad para usar el mismo patrón que PageIndex y, a continuación, aumentar la página ManageUsers.aspx de modo que la persona que visita la página pueda especificar cuántas cuentas de usuario se van a mostrar por página.

Recuperar solo los registros de la página actual, actualizar el índice de página y habilitar y deshabilitar los LinkButtons de la interfaz de paginación

Con la interfaz de paginación en su lugar y las propiedades PageIndex y PageSize agregadas, estamos listos para actualizar el método BindUserAccounts para que use la sobrecarga de FindUsersByName adecuada. Además, es necesario que este método habilite o deshabilite la interfaz de paginación en función de la página que se muestre. Al ver la primera página de datos, se deben deshabilitar los vínculos Primera y Anterior; mientras que Siguiente y Última deben deshabilitarse al ver la última página.

Actualice el método BindUserAccounts con el código siguiente:

private void BindUserAccounts()
{
 int totalRecords;
 UserAccounts.DataSource = Membership.FindUsersByName(this.UsernameToMatch + "%",this.PageIndex, this.PageSize, out totalRecords);
 UserAccounts.DataBind();

 // Enable/disable the paging interface
 bool visitingFirstPage = (this.PageIndex == 0);
 lnkFirst.Enabled = !visitingFirstPage;
 lnkPrev.Enabled = !visitingFirstPage;

 int lastPageIndex = (totalRecords - 1) / this.PageSize;
 bool visitingLastPage = (this.PageIndex >= lastPageIndex);
 lnkNext.Enabled = !visitingLastPage;
 lnkLast.Enabled = !visitingLastPage;
}

Tenga en cuenta que el número total de registros que se paginan viene determinado por el último parámetro del método FindUsersByName. Se trata de un parámetro de out, por lo que primero es necesario declarar una variable para contener este valor (totalRecords) y, a continuación, un prefijo con la palabra clave out.

Después de devolver la página especificada de las cuentas de usuario, los cuatro LinkButtons estarán habilitados o deshabilitados, dependiendo de si se está viendo la primera o la última página de datos.

El último paso es escribir el código para los cuatro controladores de eventos de Click de LinkButtons. Estos controladores de eventos deben actualizar la propiedad PageIndex y, a continuación, volver a enlazar los datos a la GridView a través de una llamada a BindUserAccounts. Los controladores de eventos Primera, Anterior y Siguiente son muy sencillos. Sin embargo, el controlador de eventos de Click para el LinkButton Última es un poco más complejo porque es necesario determinar cuántos registros se muestran para determinar el último índice de página.

protected void lnkFirst_Click(object sender, EventArgs e)
{
 this.PageIndex = 0;
 BindUserAccounts();
}

protected void lnkPrev_Click(object sender, EventArgs e)
{
 this.PageIndex -= 1;
 BindUserAccounts();
}

protected void lnkNext_Click(object sender, EventArgs e)
{
 this.PageIndex += 1;
 BindUserAccounts();
}

protected void lnkLast_Click(object sender, EventArgs e)
{
 // Determine the total number of records
 int totalRecords;
 Membership.FindUsersByName(this.UsernameToMatch + "%", this.PageIndex,this.PageSize, out totalRecords);
 // Navigate to the last page index
 this.PageIndex = (totalRecords - 1) / this.PageSize;
 BindUserAccounts();
}

Las Figuras 8 y 9 muestran la interfaz de paginación personalizada en acción. En la Figura 8 se muestra la página de ManageUsers.aspx al ver la primera página de datos de todas las cuentas de usuario. Tenga en cuenta que solo se muestran 10 de las 13 cuentas. Al hacer clic en el vínculo Siguiente o Última se produce un postback, se actualiza PageIndex a 1 y se enlaza la segunda página de cuentas de usuario a la cuadrícula (consulte la Figura 9).

The First 10 User Accounts are Displayed

Figura 8: Se muestran las 10 primeras cuentas de usuario (Haga clic para ver la imagen a tamaño completo)

Clicking the Next Link Displays the Second Page of User Accounts

Figura 9: Al hacer clic en el vínculo Siguiente se muestra la segunda página de cuentas de usuario (Haga clic para ver la imagen a tamaño completo)

Resumen

A menudo, los administradores necesitan seleccionar un usuario de la lista de cuentas. En los tutoriales anteriores hemos visto el uso de una lista desplegable rellenada con los usuarios, pero este enfoque no se escala bien. En este tutorial hemos explorado una alternativa mejor: una interfaz filtrable cuyos resultados se muestran en una GridView paginada. Con esta interfaz de usuario, los administradores pueden localizar y seleccionar de forma rápida y eficaz una cuenta de usuario entre miles.

¡Feliz programación!

Lecturas adicionales

Para obtener más información sobre los temas tratados en este tutorial, consulte los siguientes recursos:

Acerca del autor

Scott Mitchell, autor de varios 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, formador y escritor. Su último libro es Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Se puede contactar con Scott en mitchell@4guysfromrolla.com o a través de su blog en http://ScottOnWriting.NET.

Agradecimientos especiales a

Esta serie de tutoriales fue revisada por muchos revisores de gran ayuda. La revisora principal de este tutorial fue Alicja Maziarz. ¿Le interesa revisar mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4GuysFromRolla.com