跨两个页面使用 GridView 进行主/细节筛选(VB)

作者 :斯科特·米切尔

下载 PDF

在本教程中,我们将使用 GridView 列出数据库中的供应商来实现此模式。 GridView 中的每个供应商行将包含一个视图产品链接,单击该链接时,会将用户带到一个单独的页面,其中列出了所选供应商的产品。

介绍

在前面的两个教程中,我们了解了如何使用 DropDownLists 在单个网页中显示主报表/详细信息报表以显示“master”记录和 GridViewDetailsView 控件以显示“详细信息”。用于主/详细信息报表的另一种常见模式是让主记录位于一个网页上,另一个网页中显示的详细信息。 论坛网站(如 ASP.NET 论坛)是实践中这种模式的一个很好的例子。 ASP.NET 论坛由各种论坛组成,包括入门、Web 窗体、数据呈现控件等。 每个论坛由多个主题组成,每个主题由多个帖子组成。 在 ASP.NET 论坛主页上,列出了论坛。 单击论坛链接会快速将你带到一个 ShowForum.aspx 页面,其中列出了该论坛的主题。 同样,单击某个话题会转到ShowPost.aspx,并显示该话题的帖子。

在本教程中,我们将使用 GridView 列出数据库中的供应商来实现此模式。 GridView 中的每个供应商行将包含一个视图产品链接,单击该链接时,会将用户带到一个单独的页面,其中列出了所选供应商的产品。

步骤 1:将SupplierListMaster.aspxProductsForSupplierDetails.aspx页面添加到Filtering文件夹

在第三个教程中定义页面布局时,我们在BasicReportingFilteringCustomFormatting 文件夹中添加了许多“初学者”页面。 但是,我们当时没有为本教程添加初学者页面,因此请花点时间将两个新页面添加到 Filtering 文件夹: SupplierListMaster.aspxProductsForSupplierDetails.aspxSupplierListMaster.aspx 将列出“master”记录(供应商),同时 ProductsForSupplierDetails.aspx 显示所选供应商的产品。

创建这两个新页面时,肯定会将它们与 Site.master 母版页相关联。

将SupplierListMaster.aspx和ProductsForSupplierDetails.aspx页添加到筛选文件夹

图 1:向文件夹添加SupplierListMaster.aspxProductsForSupplierDetails.aspx页面Filtering

此外,在向项目添加新页面时,请务必相应地更新站点地图文件 Web.sitemap。 对于本教程,只需将页面添加到网站地图,并使用以下 XML 内容作为筛选报表 SupplierListMaster.aspx 元素的子元素: <siteMapNode>

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

注释

您可以使用 K. Scott Allen 提供的免费 Visual Studio 网站地图宏,在添加新 ASP.NET 页面时,帮助自动更新网站地图文件。

步骤 2:显示供应商列表SupplierListMaster.aspx

随着SupplierListMaster.aspxProductsForSupplierDetails.aspx页面的创建,我们的下一步是在SupplierListMaster.aspx中创建供应商的网格视图。 将 GridView 添加到页面,并将其绑定到新的 ObjectDataSource。 此 ObjectDataSource 应使用 SuppliersBLLGetSuppliers() 的方法返回所有供应商。

选择 SuppliersBLL 类的图像

图 2:选择 SuppliersBLL 类(单击以查看全尺寸图像

将 ObjectDataSource 配置为使用 GetSuppliers() 方法

图 3:将 ObjectDataSource 配置为使用 GetSuppliers() 方法(单击可查看全尺寸图像

我们需要在每个 GridView 行中包含一个标题为“查看产品”的链接,单击该链接时,用户将通过查询字符串把所选行的ProductsForSupplierDetails.aspx 值传递到SupplierID。 例如,如果用户单击东京贸易商供应商(其SupplierID值为4)的“查看产品”链接,他们应被发送到ProductsForSupplierDetails.aspx?SupplierID=4

为此,请将 HyperLinkField 添加到 GridView,这会向每个 GridView 行添加超链接。 首先单击 GridView 智能标记中的“编辑列”链接。 接下来,从左上角列表中选择 HyperLinkField,然后单击“添加”以在 GridView 的字段列表中包括 HyperLinkField。

将 HyperLinkField 添加到 GridView

图 4:将 HyperLinkField 添加到 GridView(单击以查看全尺寸图像

HyperLinkField 可配置为在每个 GridView 行中使用相同的链接文本或 URL 值,或者根据绑定到每个特定行的数据值来确定这些链接文本或 URL 值。 若要在所有行中指定静态值,请使用 HyperLinkField 或TextNavigateUrl属性。 由于我们希望链接文本对所有行相同,因此请将 HyperLinkField 的属性 Text 设置为“查看产品”。

将 HyperLinkField 的文本属性设置为查看产品

图 5:将 HyperLinkField 的属性 Text 设置为“查看产品”(单击以查看全尺寸图像

若要设置绑定到 GridView 行的基础数据的文本或 URL 值,请在DataTextFieldDataNavigateUrlFields属性中指定要拉取文本或 URL 值的数据字段。 DataTextField 只能设置为单个数据字段; DataNavigateUrlFields但是,可以设置为以逗号分隔的数据字段列表。 我们通常需要将文本或 URL 基于一组组合,包括当前行的数据字段值和一些静态标记。 例如,在本教程中,我们希望 HyperLinkField 链接的 URL 为ProductsForSupplierDetails.aspx?SupplierID=supplierID,其中每个 GridView 行的supplierID值为SupplierID。 请注意,此处需要静态值和数据驱动值: ProductsForSupplierDetails.aspx?SupplierID= 链接 URL 的部分是静态的,而该 supplierID 部分是数据驱动的,因为其值是每行自己的 SupplierID 值。

若要指示静态值和数据驱动值的组合,请使用 DataTextFormatStringDataNavigateUrlFormatString 属性。 在这些属性中,根据需要输入静态标记,然后在希望显示{0}字段或DataTextField属性的值的地方使用标记DataNavigateUrlFields。 如果DataNavigateUrlFields属性具有多个字段,则在其中插入第一个字段值的位置使用{0},插入第二个字段值的位置使用{1},以此类推。

将此应用于我们的教程,我们需要将属性设置为DataNavigateUrlFields,因为这是数据字段,我们需要按行自定义其值,并将SupplierID属性设置为DataNavigateUrlFormatStringProductsForSupplierDetails.aspx?SupplierID={0}

配置 HyperLinkField 以包含基于 SupplierID 的正确链接 URL

图 6:配置 HyperLinkField 以包含基于 SupplierID 正确链接 URL(单击以查看全尺寸图像

添加 HyperLinkField 后,可以随意自定义和重新排序 GridView 的字段。 以下标记显示了我在某些字段层面上进行轻微自定义后的 GridView。

<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>

花点时间通过浏览器查看 SupplierListMaster.aspx 页面。 如图 7 所示,页面当前列出了所有供应商,包括“查看产品”链接。 单击“查看产品”链接将引导你到ProductsForSupplierDetails.aspx,并在查询字符串中传递供应商的SupplierID

每个供应商行都包含一个查看产品链接

图 7:每个供应商行都包含一个视图产品链接(单击以查看全尺寸图像

第3步:列出供应商的产品ProductsForSupplierDetails.aspx

此时,SupplierListMaster.aspx 页面将用户重定向到 ProductsForSupplierDetails.aspx,并在查询字符串中传递所选供应商的 SupplierID。 教程的最后一步是显示 ProductsForSupplierDetails.aspx 中的 GridView 产品,其中 SupplierID 等于通过查询字符串传递的 SupplierID。 若要完成此任务,请首先将 GridView 添加到 ProductsForSupplierDetails.aspx 页面,然后使用一个名为 ProductsBySupplierDataSource 的新 ObjectDataSource 控件,调用 GetProductsBySupplierID(supplierID) 类中的 ProductsBLL 方法。

添加名为 ProductsBySupplierDataSource 的新 ObjectDataSource

图 8:添加名为 ProductsBySupplierDataSource 的新 ObjectDataSource (单击可查看全尺寸图像

选择 ProductsBLL 类

图 9:选择 ProductsBLL 类(单击以查看全尺寸图像

让 ObjectDataSource 调用 GetProductsBySupplierID(supplierID) 方法

图 10:让 ObjectDataSource 调用 GetProductsBySupplierID(supplierID) 方法(单击以查看全尺寸图像

配置数据源向导的最后一步要求我们提供方法GetProductsBySupplierID(supplierID)参数的supplierID源。 若要使用 querystring 值,请将参数源设置为 QueryString,并输入要在 QueryStringField 文本框中使用的查询字符串值的名称(SupplierID)。

来自 SupplierID Querystring 值的 supplierID 参数值的图像

图 11:从 Querystring 值填充 supplierID 参数值 SupplierID单击以查看全尺寸图像

就是这么简单! 图 12 显示了单击ProductsForSupplierDetails.aspx中的“东京交易员”链接后访问的SupplierListMaster.aspx页面。

东京贸易商提供的产品显示

图 12:东京贸易商提供的产品显示(单击查看全尺寸图像

显示供应商信息ProductsForSupplierDetails.aspx

如图 12 所示,ProductsForSupplierDetails.aspx 页面仅列出由查询字符串中指定的 SupplierID 提供的产品。 但是,如果有人被直接发送到此页面,他们将不知道图 12 显示东京商贸公司的产品。 若要解决此问题,我们还可以在此页中显示供应商信息。

首先在产品 GridView 上方添加 FormView。 创建一个名为 SuppliersDataSource 调用 SuppliersBLLGetSupplierBySupplierID(supplierID) 方法的新 ObjectDataSource 控件。

数据源的图像选择 SuppliersBLL 类

图 13:选择 SuppliersBLL 类(单击以查看全尺寸图像

让 ObjectDataSource 调用 GetSupplierBySupplierID(supplierID) 方法

图 14:让 ObjectDataSource 调用 GetSupplierBySupplierID(supplierID) 方法(单击以查看全尺寸图像

ProductsBySupplierDataSource 一样,将参数 supplierID 分配为 SupplierID querystring 值。

SupplierID 查询字符串值中的 supplierID 参数值的图像

图 15:从supplierID中的查询字符串值填充SupplierID中的参数值(单击以查看全尺寸图像

在设计视图中将 FormView 绑定到 ObjectDataSource 时,Visual Studio 将自动创建 FormView 的 ItemTemplateInsertItemTemplate并为 EditItemTemplate ObjectDataSource 返回的每个数据字段创建 Label 和 TextBox Web 控件。 由于我们只想显示供应商信息,因此可以随意删除 InsertItemTemplateEditItemTemplate。 接下来,编辑 ItemTemplate,使其在元素和 <h3> 公司名称下方的地址、城市、国家/地区和电话号码中显示供应商的公司名称。 或者,可以手动设置 FormView 的 DataSourceID 标记并创建 ItemTemplate 标记,就像我们在“使用 ObjectDataSource 显示数据”教程中所做的那样。

在这些编辑后,FormView 的声明性标记应如下所示:

<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>

图 16 显示包含上述供应商信息后页面的 ProductsForSupplierDetails.aspx 屏幕截图。

产品列表包括有关供应商的摘要

图 16:产品列表包括有关供应商的摘要(单击以查看全尺寸图像

ProductsForSupplierDetails.aspxUI 做最后的润色

为了改进此报表的用户体验,我们需要对 ProductsForSupplierDetails.aspx 页面进行一些添加。 目前,用户可以从 ProductsForSupplierDetails.aspx 页面返回供应商列表的唯一方法是单击浏览器的后退按钮。 让我们将 HyperLink 控件添加到 ProductsForSupplierDetails.aspx 链接回 SupplierListMaster.aspx的页面,为用户提供返回到主列表的另一种方法。

添加 HyperLink 控件以将用户带回SupplierListMaster.aspx

图 17:添加 HyperLink 控件以将用户返回(SupplierListMaster.aspx单击以查看全尺寸图像

如果用户单击某个供应商的“查看产品”链接,而该供应商没有任何产品,则 ProductsBySupplierDataSource ObjectDataSource 在 ProductsForSupplierDetails.aspx 中不会返回任何结果。 绑定到 ObjectDataSource 的 GridView 不会呈现任何标记,导致用户在浏览器中的页面上出现空白区域。 为了更清楚地向用户传达,没有与所选供应商关联的产品,我们可以将 GridView EmptyDataText 的属性设置为在出现此类情况时要显示的消息。 我已将此属性设置为“没有此供应商提供的产品””

默认情况下,Northwinds 数据库中的所有供应商至少提供一个产品。 但是,在本教程中,我手动修改了表 Products ,以便供应商 Escargots Nouveaux 不再与任何产品相关联。 图 18 显示了在进行此更改后 Escargots Nouveaux 的详细信息页面。

通知用户供应商不提供任何产品

图 18:通知用户供应商不提供任何产品(单击以查看全尺寸图像

概要

虽然主报表/详细信息报表可以在一个页面上同时显示主记录和详细信息记录,但在许多网站中,它们跨两个网页分开。 在本教程中,我们通过在“母版”网页中列出供应商以及“详细信息”页中列出的关联产品,来了解如何实现此类大纲/细节报告。 母版网页中的每个供应商行都包含一个链接,该链接将行的 SupplierID 值传递到详细信息页。 可以使用 GridView 的 HyperLinkField 轻松添加此类行特定的链接。

在详细信息页中,通过调用 ProductsBLL 类的 GetProductsBySupplierID(supplierID) 方法来完成检索指定供应商的产品。 参数 supplierID 值是使用 querystring 作为参数源以声明方式指定的。 我们还了解了如何使用 FormView 在详细信息页中显示供应商详细信息。

下一篇教程是主/详细信息报表的最后一篇教程。 我们将了解如何在 GridView 中显示产品列表,其中每行都有一个“选择”按钮。 单击“选择”按钮将在同一页上的 DetailsView 控件中显示该产品的详细信息。

快乐编程!

关于作者

斯科特·米切尔,七本 ASP/ASP.NET 书籍的作者和 4GuysFromRolla.com 的创始人,自1998年以来一直在与Microsoft Web 技术合作。 斯科特担任独立顾问、教练和作家。 他的最新书是 《Sams Teach Yourself ASP.NET 2.0 in 24 Hours》。 可以通过 mitchell@4GuysFromRolla.com 联系到他。

特别致谢

本教程系列由许多有用的审阅者审阅。 本教程的主要审阅者是希尔顿·吉森诺。 有兴趣查看即将发布的 MSDN 文章? 如果是这样,请给我写信。mitchell@4GuysFromRolla.com