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

作者 :Scott Mitchell

下载 PDF

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

简介

在前两个教程中,我们了解了如何使用 DropDownLists 显示“master”记录和 GridView 或 DetailsView 控件在单个网页中显示“详细信息”报表。用于大纲/详细信息报表的另一种常见模式是,在一个网页上显示主记录,并在另一个网页上显示详细信息。 与 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 参数值的图像

图 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放置一行。