Filtrado de maestros y detalles entre dos páginas con GridView (C#)

por Scott Mitchell

Descargar PDF

En este tutorial implementaremos este patrón mediante GridView para enumerar los proveedores de la base de datos. Cada fila de proveedor de GridView contendrá un vínculo Ver productos que, al hacer clic sobre el mismo, llevará al usuario a una página independiente que mostrará los productos para el proveedor seleccionado.

Introducción

En los dos tutoriales anteriores vimos cómo mostrar informes maestros y de detalles en una sola página web mediante DropDownLists para mostrar los registros "maestros" y un control GridView o DetailsView para mostrar los "detalles". Otro patrón común que se usa para los informes de maestros y detalles es tener los registros maestros en una página web y los detalles que se muestran en otro. Un sitio web de foro, como los foros de ASP.NET, es un excelente ejemplo de este patrón en la práctica. Los foros de ASP.NET se componen de diversos foros de introducción, Web Forms, controles de presentación de datos, etc. Cada foro se compone de muchos subprocesos y cada subproceso se compone de una serie de publicaciones. En la página principal de ASP.NET Foros, se muestran los foros. Al hacer clic en un foro, se le abrirá una página ShowForum.aspx, que enumera los subprocesos de ese foro. Del mismo modo, al hacer clic en un subproceso se le lleva a ShowPost.aspx, que muestra las publicaciones del subproceso en el que se hizo clic.

En este tutorial implementaremos este patrón mediante GridView para enumerar los proveedores de la base de datos. Cada fila de proveedor de GridView contendrá un vínculo Ver productos que, al hacer clic sobre el mismo, llevará al usuario a una página independiente que mostrará los productos para el proveedor seleccionado.

Paso 1: AgregarSupplierListMaster.aspxyProductsForSupplierDetails.aspxpáginas a laFilteringcarpeta

Al definir el diseño de página en el tercer tutorial, agregamos una serie de páginas "starter" en las BasicReportingcarpetas, Filteringy CustomFormatting. Sin embargo, no agregamos una página de inicio para este tutorial en ese momento, así que dedique un momento a agregar dos páginas nuevas a la Filtering carpeta: SupplierListMaster.aspx y ProductsForSupplierDetails.aspx. SupplierListMaster.aspx mostrará los registros "maestros" (los proveedores) mientras ProductsForSupplierDetails.aspx mostrará los productos para el proveedor seleccionado.

Al crear estas dos páginas nuevas, asegúrese de asociarlas a la página Site.master maestra.

Add the SupplierListMaster.aspx and ProductsForSupplierDetails.aspx Pages to the Filtering Folder

Figura 1: Agregar las páginas SupplierListMaster.aspx y ProductsForSupplierDetails.aspx a la carpeta Filtering

Además, al agregar nuevas páginas al proyecto, asegúrese de actualizar el archivo de mapa del sitio, Web.sitemap, en consecuencia. Para este tutorial, basta con agregar la página SupplierListMaster.aspx al mapa del sitio mediante el siguiente contenido XML como elemento secundario del elemento <siteMapNode> de Filtrar Informes:

<siteMapNode url="~/Filtering/SupplierListMaster.aspx"
  title="Master/Detail Across Two Pages"
  description="Master records on one page, detail records on another."
/>

Nota:

Puede ayudar a automatizar el proceso de actualización del archivo de mapa del sitio al agregar nuevas páginas de ASP.NET mediante la macro de mapa del sitio gratuita de Visual Studio de K. Scott Allen.

Paso 2: Mostrar la lista de proveedores en SupplierListMaster.aspx

Con las páginas SupplierListMaster.aspx y ProductsForSupplierDetails.aspx creadas, nuestro siguiente paso es crear GridView de proveedores en SupplierListMaster.aspx. Agregue una clase GridView a la página y enlácela a un nuevo ObjectDataSource. Este ObjectDataSource debe usar el método GetSuppliers() de la clase SuppliersBLL para devolver todos los proveedores.

Image of Data Source select the SuppliersBLL Class

Figura 2: Seleccionar la clase SuppliersBLL (haga clic para ver la imagen a tamaño completo)

Configure the ObjectDataSource to Use the GetSuppliers() Method

Figura 3: Configuración de ObjectDataSource para usar el método GetSuppliers() (haga clic para ver la imagen a tamaño completo)

Es necesario incluir un vínculo titulado Ver productos en cada fila de GridView que, cuando se hace clic, lleva al usuario a pasar ProductsForSupplierDetails.aspx en el valor SupplierID de la fila seleccionada a través de la cadena de consulta. Por ejemplo, si el usuario hace clic en el vínculo Ver productos para el proveedor de Tokyo Traders (que tiene un valor SupplierID de 4), deben enviarse a ProductsForSupplierDetails.aspx?SupplierID=4.

Para ello, agregue un HyperLinkField a GridView, que agrega un hipervínculo a cada fila de GridView. Para empezar, haga clic en el vínculo Editar columnas desde la etiqueta inteligente de GridView. A continuación, seleccione HyperLinkField en la lista de la parte superior izquierda y haga clic en Agregar para incluir HyperLinkField en la lista de campos de GridView.

Add a HyperLinkField to the GridView

Figura 4: Agregar un HyperLinkField a GridView (haga clic para ver la imagen a tamaño completo)

HyperLinkField se puede configurar para usar los mismos valores de texto o dirección URL que el vínculo de cada fila GridView o puede basar estos valores en los valores de datos enlazados a cada fila determinada. Para especificar un valor estático en todas las filas, use las propiedades Text o NavigateUrl de HyperLinkField. Puesto que queremos que el texto del vínculo sea el mismo para todas las filas, establezca la propiedad Text de HyperLinkField en Ver Productos.

Set the HyperLinkField's Text Property to View Products

Figura 5: Establecer la propiedad Text de HyperLinkField en Ver productos (haga clic para ver la imagen a tamaño completo)

Para establecer los valores de texto o dirección URL que se basarán en los datos subyacentes enlazados a la fila GridView, especifique los campos de datos de los que deben extraerse los valores de texto o dirección URL en las propiedades DataTextField o DataNavigateUrlFields. DataTextField solo se puede establecer en un único campo de datos; DataNavigateUrlFields, sin embargo, se puede establecer en una lista delimitada por comas de campos de datos. Con frecuencia, es necesario basar el texto o la dirección URL en una combinación del valor del campo de datos de la fila actual y algún marcado estático. En este tutorial, por ejemplo, queremos que la dirección URL de los vínculos de HyperLinkField sea ProductsForSupplierDetails.aspx?SupplierID=supplierID, donde supplierID es el valor SupplierID de cada fila de GridView. Tenga en cuenta que necesitamos valores estáticos y controlados por datos aquí: la parte ProductsForSupplierDetails.aspx?SupplierID= de la dirección URL del vínculo es estática, mientras que la parte supplierID está controlada por datos, ya que su valor es el propio valor SupplierID de cada fila.

Para indicar una combinación de valores estáticos y controlados por datos, use las propiedades DataTextFormatString y DataNavigateUrlFormatString. En estas propiedades, escriba el marcado estático según sea necesario y, a continuación, use el marcador {0} donde desea que aparezca el valor del campo especificado en las propiedades DataTextField o DataNavigateUrlFields. Si la propiedad DataNavigateUrlFields tiene varios campos especificados, use {0} donde desea insertar el primer valor de campo, {1} para el segundo valor de campo, etc.

Para aplicar esto a nuestro tutorial, es necesario establecer la propiedadDataNavigateUrlFields en SupplierID, ya que es el campo de datos cuyo valor necesitamos personalizar por fila, y la propiedad DataNavigateUrlFormatString en ProductsForSupplierDetails.aspx?SupplierID={0}.

Configure the HyperLinkField to Include the Proper Link URL Based Upon the SupplierID

Figura 6: Configurar HyperLinkField para incluir la dirección URL de vínculo adecuada basada en SupplierID (haga clic para ver la imagende tamaño completo)

Después de agregar HyperLinkField, no dude en personalizar y reordenar los campos de GridView. El marcado siguiente muestra GridView después de haber realizado algunas personalizaciones de nivel de campo secundarias.

<asp:GridView ID="GridView1" runat="server"
    AutoGenerateColumns="False" DataKeyNames="SupplierID"
    DataSourceID="ObjectDataSource1" EnableViewState="False">
    <Columns>
        <asp:HyperLinkField DataNavigateUrlFields="SupplierID"
            DataNavigateUrlFormatString=
            "ProductsForSupplierDetails.aspx?SupplierID={0}"
            Text="View Products" />
        <asp:BoundField DataField="CompanyName"
          HeaderText="Company" SortExpression="CompanyName" />
        <asp:BoundField DataField="City" HeaderText="City"
          SortExpression="City" />
        <asp:BoundField DataField="Country" HeaderText="Country"
          SortExpression="Country" />
    </Columns>
</asp:GridView>

Dedique un momento a ver la página SupplierListMaster.aspx a través de un explorador. Como se muestra en la figura 7, la página muestra actualmente todos los proveedores, incluido un vínculo Ver productos. Al hacer clic en el vínculo Ver productos, se le llevará a ProductsForSupplierDetails.aspx, pasando por el proveedor SupplierID en la cadena de consulta.

Each Supplier Row Contains a View Products Link

Figura 7: Cada fila de proveedor contiene un vínculo Ver productos (haga clic para ver la imagen a tamaño completo)

Paso 3: Enumerar los productos del proveedor en ProductsForSupplierDetails.aspx

En este momento, la página SupplierListMaster.aspx envía usuarios a ProductsForSupplierDetails.aspx, pasando el SupplierID del proveedor seleccionado en la cadena de consulta. El paso final del tutorial es mostrar los productos en GridView en ProductsForSupplierDetails.aspx cuyo SupplierID es igual al SupplierID pasado a través de la cadena de consulta. Para ello, agregue una clase GridView a la página ProductsForSupplierDetails.aspx mediante un nuevo control ObjectDataSource denominado ProductsBySupplierDataSource que invoca el método GetProductsBySupplierID(supplierID) de la clase ProductsBLL.

Add a New ObjectDataSource Named ProductsBySupplierDataSource

Figura 8: Agregar un nuevo objetoDataSource denominado ProductsBySupplierDataSource (haga clic para ver la imagen de tamaño completo)

Select the ProductsBLL Class

Figura 9: Seleccionar la clase ProductsBLL (haga clic para ver la imagen a tamaño completo)

Have the ObjectDataSource Invoke the GetProductsBySupplierID(supplierID) Method

Figura 10: Hacer que ObjectDataSource invoque el método GetProductsBySupplierID(supplierID) (haga clic para ver la imagen a tamaño completo)

El último paso del Asistente para configurar orígenes de datos nos pide que proporcionemos el origen del parámetro GetProductsBySupplierID(supplierID) del método supplierID. Para usar el valor de la cadena de consulta, establezca el origen del parámetro en QueryString y escriba el nombre del valor de la cadena de consulta que se va a usar en el cuadro de texto QueryStringField (SupplierID).

Image of the supplierID Parameter Value from the SupplierID Querystring Value

Figura 11: Rellenar el valor del parámetro supplierID del valor de cadena de consulta de SupplierID (haga clic para ver la imagen a tamaño completo)

Eso es todo. En la figura 12 se muestra la página ProductsForSupplierDetails.aspx cuando se visita haciendo clic en el vínculo Tokio Traders desde SupplierListMaster.aspx.

The Products Supplied by Tokyo Traders are Shown

Figura 12: Los productos suministrados por Tokyo Traders se muestran (haga clic para ver la imagen a tamaño completo)

Mostrar información del proveedor en ProductsForSupplierDetails.aspx

Como se muestra en la figura 12, la página ProductsForSupplierDetails.aspx simplemente muestra los productos proporcionados por el SupplierID especificado en la cadena de consulta. Sin embargo, alguien enviado directamente a esta página no sabría que la figura 12 muestra los productos de Tokyo Traders. Para solucionar esto también podemos mostrar la información del proveedor en esta página.

Comience agregando un FormView encima de GridView de productos. Cree un nuevo control ObjectDataSource denominado SuppliersDataSource que invoque el método SuppliersBLL de la clase GetSupplierBySupplierID(supplierID).

Image of Data Source adding the SuppliersBLL Class

Figura 13: Seleccionar la clase SuppliersBLL (haga clic para ver la imagen a tamaño completo)

Have the ObjectDataSource Invoke the GetSupplierBySupplierID(supplierID) Method

Figura 14: Hacer que ObjectDataSource invoque el método GetSupplierBySupplierID(supplierID) (haga clic para ver la imagen a tamaño completo)

Al igual que con el ProductsBySupplierDataSource, tenga asignado el parámetro supplierID el valor del valor de querystring SupplierID.

Image of the supplierID Parameter Value

Figura 15: Rellenar el valor del parámetro supplierID del valor de cadena de consulta de SupplierID (haga clic para ver la imagen a tamaño completo)

Al enlazar FormView a ObjectDataSource en la vista Diseño, Visual Studio creará automáticamente ItemTemplate, InsertItemTemplate y EditItemTemplate de FormView, con controles Web Label y TextBox para cada uno de los campos de datos devueltos por ObjectDataSource. Puesto que solo queremos mostrar información de proveedor no dude en quitar InsertItemTemplate y EditItemTemplate. A continuación, edite ItemTemplate para que muestre el nombre de la compañía del proveedor en un elemento <h3> y la dirección, ciudad, país o región y número de teléfono debajo del nombre de la empresa. Como alternativa, puede establecer manualmente DataSourceID de FormView y crear el marcado ItemTemplate, como hicimos en el tutorial "Mostrar datos con ObjectDataSource".

Después de editar el marcado declarativo de FormView debe ser similar al siguiente:

<asp:FormView ID="FormView1" runat="server" DataKeyNames="SupplierID"
    DataSourceID="suppliersDataSource" EnableViewState="False">
    <ItemTemplate>
        <h3><%# Eval("CompanyName") %></h3>
        <p>
            <asp:Label ID="AddressLabel" runat="server"
                Text='<%# Bind("Address") %>'></asp:Label><br />
            <asp:Label ID="CityLabel" runat="server"
                Text='<%# Bind("City") %>'></asp:Label>,
            <asp:Label ID="CountryLabel" runat="server"
                Text='<%# Bind("Country") %>'></asp:Label><br />
            Phone:
            <asp:Label ID="PhoneLabel" runat="server"
                Text='<%# Bind("Phone") %>'></asp:Label>
        </p>
    </ItemTemplate>
</asp:FormView>

En la figura 16 se muestra una captura de pantalla de la página ProductsForSupplierDetails.aspx después de incluir la información del proveedor detallada anteriormente.

The List of Products Includes a Summary About the Supplier

Figura 16: La lista de productos incluye un resumen sobre el proveedor (haga clic para ver la imagen a tamaño completo)

Aplicación de los toques finales para la interfaz de usuario de ProductsForSupplierDetails.aspx

Para mejorar la experiencia del usuario para este informe, hay un par de adiciones que debemos realizar en la página ProductsForSupplierDetails.aspx. Actualmente, la única forma en que un usuario puede volver desde la página ProductsForSupplierDetails.aspx a la lista de proveedores es hacer clic en el botón Atrás del explorador. Vamos a agregar un control HyperLink a la página ProductsForSupplierDetails.aspx que se vincula a SupplierListMaster.aspx, lo que proporciona otra manera de que el usuario vuelva a la lista maestra.

Add a HyperLink Control to Take the User Back to SupplierListMaster.aspx

Figura 17: Agregar un control HyperLink para devolver al usuario a SupplierListMaster.aspx (haga clic para ver la imagen a tamaño completo)

Si el usuario hace clic en el vínculo Ver productos de un proveedor que no tiene ningún producto, el ObjectDataSource ProductsBySupplierDataSource en ProductsForSupplierDetails.aspx no devolverá ningún resultado. GridView enlazado a ObjectDataSource no representará ningún marcado que produzca una región en blanco en la página del explorador del usuario. Para comunicar con más claridad al usuario que no hay productos asociados con el proveedor seleccionado, podemos establecer la propiedad EmptyDataText de GridView en el mensaje que queremos mostrar cuando surge tal situación. He establecido esta propiedad en "No hay productos proporcionados por este proveedor"

De forma predeterminada, todos los proveedores de la base de datos Northwinds proporcionan al menos un producto. Sin embargo, para este tutorial he modificado manualmente la tabla Products para que el proveedor Escargots Nouveaux ya no esté asociado a ningún producto. En la figura 18 se muestra la página de detalles de Escargots Nouveaux después de realizar este cambio.

Users are Informed that the Supplier Doesn't Provide Any Products

Figura 18: Se informa a los usuarios de que el proveedor no proporciona ningún producto (haga clic para ver la imagen a tamaño completo)

Resumen

Aunque los informes maestros y de detalles pueden mostrar los registros maestros y de detalles en una sola página, en muchos sitios web se separan en dos páginas web. En este tutorial hemos visto cómo implementar este informe maestro y de detalles teniendo los proveedores enumerados en GridView en la página web "maestra" y los productos asociados enumerados en la página de "detalles". Cada fila de proveedor de la página web maestra contenía un vínculo a la página de detalles que se pasó a lo largo del valor SupplierID de la fila. Estos vínculos específicos de fila se pueden agregar fácilmente mediante HyperLinkField de GridView.

En la página de detalles que recupera esos productos para el proveedor especificado se realizó invocando el método GetProductsBySupplierID(supplierID) de la clase ProductsBLL. El valor del parámetro supplierID se especificó mediante declaración mediante la cadena de consulta como origen del parámetro. También hemos visto cómo mostrar los detalles del proveedor en la página de detalles mediante un FormView.

Nuestro siguiente tutorial es el último en relación con los informes maestros y de detalles. Veremos cómo mostrar una lista de productos en GridView donde cada fila tiene un botón Seleccionar. Al hacer clic en el botón Seleccionar se mostrarán los detalles del producto en un control DetailsView de la misma página.

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

Agradecimientos especiales a

Muchos revisores han evaluado esta serie de tutoriales. El revisor principal de este tutorial fue Hilton Giesenow. ¿Le interesa revisar mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4GuysFromRolla.com.