简介
前两篇教程中介绍了如何使用 DropDownLists 在一个 Web 页面上显示主/明细报表,以便显示“主要”记录和 GridView 或 DetailsView 控件,从而显示“详细信息”。用于主/明细报表的另一种常见模式是在一个 Web 页面上显示主要记录,在另一个 Web 页面上显示详细信息。论坛网站,如 ASP.NET 论坛就是使用此类模式的极佳例子。ASP.NET 论坛包含各种论坛——Getting Started、Web Forms、Data Presentation Controls 等。每个论坛有多个主题,每个主题下又有大量帖子。ASP.NET 论坛主页上提供了论坛列表。单击其中的论坛便可迅速打开响应的 ShowForum.aspx 页面,列出该论坛的主题。同样,单击主题便可打开相应 ShowPost.aspx 页面,显示该主题下的帖子。
本教程中,我们将使用 GridView 列出数据库中的供应商。GridView 中的每行供应商将含有一个 View Products 链接,单击该链接,将单独出现一个页面,显示所选取的供应商的产品。
步骤 1:向 Filtering 文件夹添加 SupplierListMaster.aspx 和 ProductsForSupplierDetails.aspx 页面
我们定义第三篇教程的页面布局时,在BasicReporting 、Filtering 、和 CustomFormatting 文件夹中添加了“ 初学者” 页面。但当时还未为本教程添加初学者页面。因此,您需要花点时间向 Filtering 文件添加两个新页面:SupplierListMaster.aspx 和 ProductsForSupplierDetails.aspx 。SupplierListMaster.aspx 将列出“主要”记录(供应商, ProductsForSupplierDetails.aspx 则显示选定供应商的产品。
新建这两个页面时,请务必将它们与 Site.master 母版页 相关联。
图1 :向 Filtering 文件夹添加 SupplierListMaster.aspx 和ProductsForSupplierDetails.aspx 页面
此外,向项目添加新页面时,务必对站点地图文件 Web.sitemap 作相应更新。本教程中只需使用如下 XML 内容向网站地图中添加 SupplierListMaster.aspx 作为Filtering 报表 <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 Site Map Macro 添加新ASP.NET 页面时可以使站点地图文件的更新过程自动化。
步骤2 :在SupplierListMaster.aspx 中显示供应商列表
创建了SupplierListMaster.aspx 和ProductsForSupplierDetails.aspx 页面后,下一步是在SupplierListMaster.aspx 中创建供应商的 GridView 。向页面添加一个 GridView 并将其绑定到一个新的 ObjectDataSource 。此 ObjectDataSource 应使用 SuppliersBLL 类的 GetSuppliers() 方法来返回所有供应商。
图2 :选择 SuppliersBLL 类
图3 :配置 ObjectDataSource 使其使用 GetSuppliers() 方法
我们需要在GridView 的每行中包含一个名为 View Products 的链接。用户单击此链接即可打开 ProductsForSupplierDetails.aspx 页面,该页面通过查询字符串传递选中行的 SupplierID 值。例如,如果用户单击 Tokyo Traders 供应商(其 SupplierID 的值为 4 )的 View Products 链接,将打开页面 ProductsForSupplierDetails.aspx?SupplierID=4 。
要添加此链接,只需向GridView 添加一个 HyperLinkField ,即可向每个GridView 行添加一个超链接。首先,单击 GridView 的智能标记上的 Edit Columns 链接。然后,选择左上角列表中的 HyperLinkField 并单击 Add 将 HyperLinkField 添加到 GridView 的字段列表中。
图4 :向 GridView 添加一个 HyperLinkField
可以配置HyperLinkField 在GridView 的每行都使用相同的文本或URL 值,或者赋值为绑定到特定每行的数据值。要跨所有行指定一个固定值,使用 HyperLinkField 的 Text 或 NavigateUrl 属性。由于我们希望所有行的链接文本都相同,将 HyperLinkField 的 Text 属性设为 View Products 。
图5 :将 HyperLinkField 的 Text 属性设为 View Products
要通过设置使文本或 URL 值赋值为绑定到 GridView 行的下层数据,应指定从DataTextField 或 DataNavigateUrlFields 属性获取数据字段或 URL 值。 DataTextField 只能设置为单个数据字段。但 DataNavigateUrlFields 可以设置为一个逗号分隔的数据字段列表。我们经常需要将文本或 URL 赋值为当前行中数据字段值和某个静态标记的组合。例如在本教程中,我们想将 HyperLinkField 的链接的 URL 设为 ProductsForSupplierDetails.aspx?SupplierID=supplierID ,其中 supplierID 为 GridView 中每行的 SupplierID 值。注意,我们在这里需要设置静态和数据驱动的值:链接的 URL 中 ProductsForSupplierDetails.aspx?SupplierID= 部分是静态的; supplierID 部分则是数据驱动的,其值为每一行自身的 SupplierID 值。
为了生成一个包含静态值和数据驱动值的组合,使用DataTextFormatString 和DataNavigateUrlFormatString 属性。在这两个属性中,根据需要输入静态标记,然后在你希望出现字段值的(这个字段值是由 DataTextField 或 DataNavigateUrlFields 属性指定的)位置使用标记 {0} 。如果 DataNavigateUrlFields 属性有多个指定的字段,则在希望插入第一个字段值的位置使用 {0} ,希望插入第二个字段值的位置使用 {1} ,依此类推。
对于本教程而言,我们需要将DataNavigateUrlFields 属性设为 SupplierID—— 因为对于这个数据字段的值我们需要逐行自定义,并将DataNavigateUrlFormatString 属性设为ProductsForSupplierDetails.aspx?SupplierID={0} 。
图6 :根据 SupplierID 配置 HyperLinkField 使其包含恰当的链接 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>
使用的查询字符串的名称 ( SupplierID )。
图11 :用 SupplierID 查询字符串的值为 supplierID 参数赋值
这样就可以了!图12 显示了通过单击 SupplierListMaster.aspx 上的Tokyo Traders 链接显示的 ProductsForSupplierDetails.aspx 页面。
图12 :显示 Tokyo Traders 提供的产品
在ProductsForSupplierDetails.aspx 中显示供应商信息
如图12 所示,ProductsForSupplierDetails.aspx 页面只列出了查询字符串中指定的 SupplierID 提供的产品。但直接进入此页面的用户并不知道图 12 显示的是 Tokyo Trader 的产品。要解决这个问题,可以在这个页面上同时显示供应商信息。
首先,在产品GridView 上方添加一个 FormView 。新建一个名为SuppliersDataSource 的 ObjectDataSource 控件,调用SuppliersBLL 类的 GetSupplierBySupplierID(supplierID) 方法。
图13 :选择 SuppliersBLL 类
图14 :使 ObjectDataSource 调用GetSupplierBySupplierID(supplierID) 方法
与ProductsBySupplierDataSource 相同,将 supplierID 参数赋值为 SupplierID 查询字符串的值。
图15 :用 SupplierID 查询字符串的值为 supplierID 参数赋值
在Design 视图中将 FormView 绑定到ObjectDataSource 时,Visual Studio 将根据ObjectDataSource 返回的每个数据字段,自动创建 FormView 的 带有 Label 和 TextBox Web 控件的 ItemTemplate 、InsertItemTemplate 和 EditItemTemplate 。由于我们只想显示供应商信息,因此您可以根据需要删除 InsertItemTemplate 和 EditItemTemplate 。然后,编辑 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.aspx 用户界面进行最后修饰
为提高此报表的用户体验,应采用多种方法对 ProductsForSupplierDetails.aspx 页面进行修饰。目前用户只有一种方法可从 ProductsForSupplierDetails.aspx 页面返回到供应商列表,即单击浏览器的返回按钮。我们需要向 ProductsForSupplierDetails.aspx 页面添加一个 HyperLink 控件,链接到 SupplierListMaster.aspx 页面,让用户多一种方式返回主列表。
图17 :添加一个 HyperLink 控件使用户返回 SupplierListMaster.aspx 页面
如果用户单击某个没有任何产品的供应商的View Products 链接,那么 ProductsForSupplierDetails.aspx 页面中的 ProductsBySupplierDataSource ObjectDataSource 不会返回任何结果。绑定到 ObjectDataSource 的 GridView 不会提交任何标记,用户浏览器的页面上将出现一块空白区域。为使用户更清楚地了解没有任何产品与选中的供应商相关联,可以将 GridView 的 EmptyDataText 属性设为我们希望在出现此情况时显示的消息。笔者将该属性设为“ There are no products provided by this supplier ”(此供应商没有提供任何产品)。
默认情况下,Northwinds 数据库中的每个供应商都提供至少一种产品。但本教程中笔者手动更改了Products 表,使供应商 Escargots Nouveaux 不关联任何产品。图 18 为此更改后的 Escargots Nouveaux 的详细信息页面。
图18 :用户将被告知此供应商不提供任何产品
小结
主/ 明 细报表可以将主要记录和详细记录显示在单个页面中,而在很多网站中他们是在两个页面单独显示的。本教程中,我们介绍了如何在“主” Web 页面的 GridView 列表中显示供应商、在“详细信息”页面中显示相关产品,用这种方法实现此类主 / 明细报表。主 Web 页面上的每个供应商行都包含一个链接,指向该行的 SupplierID 值的详细信息页面。使用 GridView 的 HyperLinkField 可以轻松添加这些特定行的链接。
在详细信息页面上,通过调用 ProductsBLL 类的 GetProductsBySupplierID(supplierID) 方法来检索指定供应商的产品。使用查询字符串作为参数源,声明式为 supplierID 参数赋值。本教程还介绍了如何使用 FormView 在详细信息页面中显示供应商详细信息。
下一篇教程是有关主/ 明细报表的最后一篇。该教程将介绍如何用每一行都有一个Select 按钮的 GridView 显示产品列表。单击 Select 按钮,即可在该页面的 DetailsView 控件中显示该产品的详细信息。
快乐编程!