使用 GridView (VB) 跨两个页面筛选母版/详细信息

作者 :Scott Mitchell

下载 PDF

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

简介

在前两个教程中,我们了解了如何使用 DropDownLists 显示“master”记录和 GridViewDetailsView 控件在单个网页中显示“详细信息”报表。用于大纲/详细信息报表的另一种常见模式是,在一个网页上显示主记录,并在另一个网页上显示详细信息。 与 ASP.NET 论坛一样,论坛网站在实践中就是此模式的一个很好的示例。 ASP.NET 论坛由各种论坛组成,入门、Web Forms、数据呈现控件等。 每个论坛由多个主题组成,每个主题由多个帖子组成。 ASP.NET 论坛主页上列出了论坛。 单击论坛会将您带至一个 ShowForum.aspx 页面,其中列出了该论坛的主题。 同样,单击某个线程会转到 ShowPost.aspx,其中显示所单击线程的帖子。

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

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

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

创建这两个新页面时,请务必将它们与 Site.master 母版页相关联。

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

图 1:将 SupplierListMaster.aspxProductsForSupplierDetails.aspx Pages 添加到 Filtering 文件夹

此外,向项目添加新页面时,请务必相应地更新站点地图文件 Web.sitemap。 对于本教程, SupplierListMaster.aspx 只需使用以下 XML 内容作为筛选报表 <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.aspx创建 和 ProductsForSupplierDetails.aspx 页面后,下一步是在 中创建SupplierListMaster.aspx供应商的 GridView。 将 GridView 添加到页面,并将其绑定到新的 ObjectDataSource。 此 ObjectDataSource 应使用 SuppliersBLL 类的 GetSuppliers() 方法来返回所有供应商。

选择 SuppliersBLL 类的图像

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

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

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

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

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

将 HyperLinkField 添加到 GridView

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

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

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

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

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

若要指示静态值和数据驱动值的组合,请使用 DataTextFormatStringDataNavigateUrlFormatString 属性。 在这些属性中,根据需要输入静态标记,然后使用要在 或 DataNavigateUrlFields 属性中指定的DataTextField字段值显示位置的标记{0}DataNavigateUrlFields如果属性指定了多个字段,请使用{0}要插入第一个字段值的位置、{1}第二个字段值等。

将此应用于我们的教程,我们需要将 DataNavigateUrlFields 属性设置为 SupplierID,因为这是需要按行自定义其值的数据字段,并将 DataNavigateUrlFormatString 属性设置为 ProductsForSupplierDetails.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,在 querystring 中传递供应商的 SupplierID

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

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

步骤 3:在 中列出供应商的产品ProductsForSupplierDetails.aspx

此时, SupplierListMaster.aspx 页面正在将用户发送到 ProductsForSupplierDetails.aspx,并在 querystring 中传递所选供应商的 SupplierID 。 本教程的最后一步是显示 GridView 中的 ProductsForSupplierDetails.aspx 产品,其 SupplierID 等于 SupplierID 通过 querystring 传入的 。 若要完成此目的,请先将 GridView 添加到ProductsForSupplierDetails.aspx页面,使用名为 ProductsBySupplierDataSource 的新 ObjectDataSource 控件,该控件从 ProductsBLL 类调用 GetProductsBySupplierID(supplierID) 方法。

添加名为 Products 的新的 ObjectDataSourceBySupplierDataSource

图 8:添加名为 ProductsBySupplierDataSource 的新对象DataSource (单击以查看全尺寸图像)

选择 ProductsBLL 类

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

让 ObjectDataSource 调用 GetProductsBySupplierID (supplierID) 方法

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

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

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

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

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

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

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

在 中显示供应商信息ProductsForSupplierDetails.aspx

如图 12 所示,该 ProductsForSupplierDetails.aspx 页只列出了由 querystring 中指定的 提供 SupplierID 的产品。 但是,直接发送到此页面的人不知道图 12 显示了东京贸易商的产品。 为了解决此问题,我们还可以在此页中显示供应商信息。

首先,在产品 GridView 上方添加 FormView。 创建名为 SuppliersDataSource 的新 ObjectDataSource 控件,该 SuppliersBLL 控件调用类的 GetSupplierBySupplierID(supplierID) 方法。

数据源的图像选择 SuppliersBLL 类

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

让 ObjectDataSource 调用 GetSupplierBySupplierID (supplierID) 方法

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

与 一样, ProductsBySupplierDataSourcesupplierID 参数分配查询字符串值 SupplierID 的值。

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

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

将 FormView 绑定到设计视图中的 ObjectDataSource 时,Visual Studio 将自动为 ObjectDataSource 返回的每个数据字段创建带有 Label 和 TextBox Web 控件的 FormView ItemTemplate的 、 InsertItemTemplateEditItemTemplate 。 由于我们只想显示供应商信息,因此可以随意删除 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:产品列表包括有关供应商的摘要 (单击以查看全尺寸图像)

为 UI 应用最终触摸ProductsForSupplierDetails.aspx

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

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

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

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

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

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

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

总结

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

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

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

编程快乐!

关于作者

斯科特·米切尔是七本 ASP/ASP.NET 书籍的作者和 4GuysFromRolla.com 的创始人,自 1998 年以来一直在使用 Microsoft Web 技术。 Scott 担任独立顾问、培训师和作家。 他的最新一本书是 山姆斯在 24 小时内 ASP.NET 2.0。 可以在 上mitchell@4GuysFromRolla.com联系他,也可以通过他的博客(可在 中找到http://ScottOnWriting.NET)。

特别感谢

本教程系列由许多有用的审阅者审阅。 本教程的首席审阅者是希尔顿·吉森诺。 有兴趣查看我即将发布的 MSDN 文章? 如果是,请在 处mitchell@4GuysFromRolla.com放置一行。