ASP.NET 2.0中的数据操作之九:跨页面的主/从报表

导言

  在前面的两篇教程中,我们看到了如何在单一页面中显示主/从报表, 它使用DropDownList显示主记录,使用GridView或DetailsView显示详细信息. 另外一种常见的主/从报表模式是在一个页面中显示主记录而在另一个页面中显示详细信息.互联网上的论坛,如www.asp.net ,就是该模式在实际应用中非常典型例子. Asp.Net论坛由多个子论坛组成: Getting Started, Web Forms, Data Presentation Controls 等等. 每个子论坛包含多个主题, 每个主题又由多个贴子组成. 在asp.net论坛主页上列出了这些子论坛,单击其中一个论坛会转到ShowForum.aspx页面, 该页面列出了这个子论坛所包含的主题. 同样,单击一个主题会转向ShowPost.aspx, 该页面显示所单击主题的贴子.

  在这篇教程中,我们将通过使用GridView列出供应商来实现该模式. GridView中的每行(一行便是一个供应商)包含一个”查看产品”的链接. 该链接在单击时会转到另外一个页面, 这个页面显示选中供应商的所有产品.

Step 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内容做为元素的子节点

提示:使用K. Scott Allen的免费的Visual Studio Site Map Macro可以帮助你在新增ASP.NET页时自动地更新站点地图.

Step 2: SupplierListMaster.aspx中显示供应商列表

  添加SupplierListMaster.aspx 和 ProductsForSupplierDetails.aspx后,接下来就是要在SupplierListMaster.aspx页面上创建一个显示供应商的GridView. 添加一个GridView到页面上并绑定到一个新的ObjectDataSource, 这个ObjectDataSource应该使用SuppliersBLL类的GetSuppliers()方法返回所有供应商.

图2: 选择 SuppliersBLL 类

图3: 配置ObjectDataSource 使用GetSuppliers() 方法

  我们需要在每个GridView行中包含一个”查看产品”链接,单击时该链接会转到ProductsForSupplierDetails.aspx页面, 并在查询字符串(querystring)传递选定行的SupplierID值.比如如果用户单击了供应商Tokyo Traders(SupplierID值为4)的”查看产品”链接,将会转到ProductsForSupplierDetails.aspx?SupplierID=4.

  要实现该功能, 给GridView添加一个HyperLinkField列, 它会为每个GridView行增加一个链接. 首先在GridView智能标记上单击编辑列链接. 然后在左上角的列表中选择HyperLinkField并单击新增把HyperLinkField添加到GridView的字段列表中.

图4: 添加 HyperLinkField 到GridView

  HyperLinkField可以被配置为在每一个GridView行中使用相同的文本或URL值,或是让这些值基于绑定到特定行的数据值. 要指定一个所有行都一样的静态值使用HyperLinkField的Text或NavigateUrl属性. 因为我们想让每一行的链接文本一致,设置HyperLinkField的Text属性为”查看产品”.

图5: 设置HyperLinkField的Text属性为”查看产品”

  要让text 或URL基于绑定到GridView行的底层数据, 可能通过DataTextField 或 DataNavigateUrlFields指定Text或URL要从中获取数据的数据字段. DataTextField只能设置为一个单一的数据字段; DataNavigateUrlFields可以设置为一个以逗号分隔的数据字段列表. 我们需要让TEXT或URL基于当前行的数据字段值和一些标记. 比如在这篇教程中,我们希望 HyperLinkField的链接URL是ProductsForSupplierDetails.aspx?SupplierID=supplierID. 其中supplierID是GridView的每个行的supplierID值. 注意我们需要静态值和数据驱动值. ProductsForSupplierDetails.aspx?SupplierID=这部分是静态值.而supplierID部分便是数据驱动的, 它的值是每一行的SupplierID值.

  要指定静态值和数据驱动值的混合物, 使用DataTextFormatString和DataNavigateUrlFormatString属性. 在这些属性中按需要输入静态文本,要显示DataTextField或DataNavigateUrlFields属性中特定的字段时使用{0}标记. 如果DataNavigateUrlFields中有多个字段,在需要第一个字段时使用{0}, 第二个字段使用{1},以此类推.

  对于我们这篇教程来说, 我们需要设置DataNavigateUrlFields为SupplierID, 因为我们需要使用该数据字段自定义每行的链接.

图6: 配置HyperLinkField 使用合适的基于SupplierID 的链接地址.

  添加了HyperLinkField后, 可以自定义及重新排列GridView的字段. 下面是我做了修改后的标记 (markup):

  在浏览器中访问一下SupplierListMaster.aspx. 如图7所示, 页面列出了所有的供应商,每个供应商包含”查看产品”链接. 单击”查看产品”链接会转到ProductsForSupplierDetails.aspx, 并在查询字符串中传递供应商的SupplierID值.

图 7: 每个供应商都包含”查看产品”链接.

Step 3: 在ProductsForSupplierDetails.aspx上列出供应商的产品

  SupplierListMaster.aspx页面使用户转到ProductsForSupplierDetails.aspx, 并在查询字符串中传递选择的供应商的SupplierID值. 本篇教程的最后一步是在ProductsForSupplierDetails.aspx 页面上的GridView中显示产品. 要实现该功能首先添加GridView到ProductsForSupplierDetails.aspx上,并使用一个新的命名为ProductsBySupplierDataSource的ObjectDataSource控件, 该控件调用ProductsBLL 类的GetProductsBySupplierID(supplierID)方法.

图8: 添加一个新的命名为 ProductsBySupplierDataSource 的ObjectDataSource

图9: 选择ProductsBLL 类

图10: 让ObjectDataSource 调用 GetProductsBySupplierID(supplierID) 方法

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

图11: 使用查询字符串中的SupplierID值做为supplierID 参数的值

这样就可以了! 图12显示了当我们在SupplierListMaster.aspx页面中单击Tokyo Traders供应商的”查看产品”链接时所看到的样子.

图12: 显示Tokyo Traders 供应商的产品

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

如图12所示, ProductsForSupplierDetails.aspx只列出了通过在查询字符串中指定的SupplierID的供应商的产品. 然而, 有些人会直接到达该页, 这样他们就不清楚图12中正中显示Tokyo Trader的产品了. 要修正这个问题, 我们可以在页面上显示供应商的信息.

在GridView上方添加一个FormView. 创建一个ObjectDataSource控件并命名为SuppliersDataSource. 该控件调用SuppliersBLL类的GetSupplierBySupplierID(supplierID)方法.

图13: 选择 SuppliersBLL 类

图14: 让ObjectDataSource 调用 GetSupplierBySupplierID(supplierID) 方法

使用查询字符串中SupplierID的值为ProductsBySupplierDataSource的supplierID参数赋值.

图15: 让supplierID 参数使用查询字符串中的SupplierID 的值

  在设计视图中绑定FormView到ObjectDataSource时, Visual Studio 将会自动的创建FormView的ItemTemplate, InsertItemTemplate 和 EditItemTemplate 三个模板, 这些模板使用Label和TextBox Web控件来呈现从ObjectDataSource返回的数据. 因为我们只需要显示供应商信息, 可以移除InsertItemTemplate 和 EditItemTemplat模板. 然后,编辑ItemTemplate模板,使它在标签中显示供应商的公司名称, 在公司名称下面显示地址,城市,国家和电话号码. 另外你也可以手工设置 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

  如果用户单击了某个供应商的”查看产品”链接,而该供应商又没有任何产品, ProductsForSupplierDetails.aspx 上的ProductsBySupplierDataSource ObjectDataSource将不会返回任何结果. 绑定到ObjectDataSource的GridView不会呈现任何标记, 在用户的浏览器中显示为空白. 要明确的告诉用户没有与选定供应商关联的产品,我们可以设置GridView的EmptyDataText属性为当出现这种情况是我们想要显示的消息. 我们把它设置为:” 没有这个供应商的产品…”;

  默认情况下, Northwinds数据库中所有的供应商提供了至少一个产品. 但是, 在本篇教程中我已经手工修改了产品表, 这样供应商Escargots Nouveaux不再关联任何产品. 图18显示了修改后的供应商Escargots Nouveaux的详细页面.

图18: 提示用户该供应商没有提供任何产品.

总结

  主/从报表可以在一个页面上同时显示主记录和明细记录,在很多的网站上, 主/从记录也被分开显示在两个页面上. 在这篇教程中我们看到了如何实现这种报表, 该报表在主页面上用GridView显示供应商列表, 在明细页显示关联的产品列表. 主页面上的每个供应商都包含一个指定明细页面的链接, 并传递 SupplierID值. 这样的特定行的链接使用GridView的HyperLinkField可以很容易实现.

  明细页中获取指定供应商的产品是通过调用ProductsBLL类的GetProductsBySupplierID(supplierID)方法实现的. supplierID参数值由查询字符串中指定. 我们同样也看到了如何在明细页中使用FormView显示供应商详细信息

  下一篇教程是主/从报表的最后一部分. 我们将会看到如何在GridView中列出产品, GridView中的每行有一个选择按钮. 单击选择按钮会在同一页的DetailsView中显示这个产品的详细信息.

祝编程愉快!

作者简介

Scott Mitchell,著有六本ASP/ASP.NET方面的书,是4GuysFromRolla.com的创始人,自1998年以来一直应用微软Web技术。Scott是个独立的技术咨询顾问,培训师,作家,最近完成了将由Sams出版社出版的新作,24小时内精通ASP.NET 2.0。他的联系电邮为mitchell@4guysfromrolla.com,也可以通过他的博客http://scottonwriting.net/与他联系。

(0)

相关推荐

  • 在ASP.NET 2.0中操作数据之十:使用 GridView和DetailView实现的主/从报表

    导言 在前面的教程我们看到了如何使用两个页面(一个主页,用于列出供应商; 一个明细页,用于显示选定供应商提供的产品)创建主/从报表 . 这种两个页面的报表格式也可以集中在一个页面上. 这篇教程将会使用一个GridView, 它的每一行都包含产品的名称和单价以及一个选择按钮. 单击一个产品的选择按钮会在同一页的DetailsView控件上显示该产品的全部详细信息. 图 1: 单击选择按钮显示产品明细 Step 1: 创建一个可选择行的GridView 回想一下前面的跨页的主/从报表, 它的每个主记

  • ASP.NET 2.0中的数据操作之七:使用DropDownList过滤的主/从报表

    导言 主/从报表是一种很常见的报表, 这类报表中首先会显示一些主记录. 然后用户可以深入(追溯)某条主记录来查看该主记录的详情. 主/从报表是显示一对多关系的理想选择, 比如一个报表显示所有的产品类别,然后根据用户选择的特定类别显示与之关联的产品. 另外, 主/从表在显示"宽"表(有很多列的表)的详细信息时也很有用.例如主/从报表的主表部分显示数据库中产品表的产品名称和单价, 具体到某一个产品时再显示其他的产品字段(类别,供应商,单位数量,等等). 有很多方法可以实现主/从报表. 在这

  • ASP.NET 2.0中的数据操作之八:使用两个DropDownList过滤的主/从报表

    导言 在前面的指南中我们研究了如何显示一个简单的主/从报表, 该报表使用DropDownList和GridView控件, DropDownList填充类别,GridView显示选定类别的产品. 这类报表用于显示具有一对多关系的记录时非常合适, 同时它也可以很容易的被扩展以显示多个一对多关系的数据. 比如, 一个订单系统应该包含表示客户,订单和订单明细的表. 一个客户也许有多个订单,每个订单又包含多条订单项. 这样的数据可以使用两个DropDownList和一个GridView呈现给用户. 第一个

  • 在ASP.NET 2.0中操作数据之六:编程设置ObjectDataSource的参数值

    导言 正如我们在上一节的教程中所看到的,有很多可供选择的方式把参数的值传递到OjbectDataSource的方法里.假如参数值是采用硬编码方式,来源于页面上的一个Web控件,又或者其他可被数据源Parameter对象读取的源,那么这个值可以绑定到输入参数而不需要写一行的代码. 然而有些时候,参数值来自某些在数据源的内置Parameter对象里还没有计算出来的源.假如我们的站点支持我们的考虑那么我们也许希望参数基于当前登录用户.又或者我们在参数传送到ObjectDataSource的隐含对象的方

  • 在ASP.NET 2.0中操作数据之二:创建一个业务逻辑层

    导言 本教程的第一节所描述的数据访问层(Data Access Layer,以下简称为DAL)已经清晰地将表示逻辑与数据访问逻辑区分开了.不过,即使DAL将数据访问的细节从表示层中分离出来了,可它却不能处理任何的业务规则.比如说,我们可能不希望产品表中那些被标记为"停用"的产品的"分类编号"或"供应商编号"被更新:我们还可能需要应用一些资历规则,比如说我们都不希望被比自己的资历还要浅的人管理.另外一个比较常见的情况就是授权,比如说只有那些具有特殊

  • [翻译]Scott Mitchell 的ASP.NET 2.0数据教程

    Scott Mitchell 的ASP.NET 2.0数据教程目录索引 01.创建一个数据访问 02.创建一个业务逻辑层 03.母板页和站点导航 04.使用ObjectDataSource展现数据 05.声明参数 06.编程设置ObjectDataSource的参数值 07.使用DropDownList过滤的主/从报表 08.使用两个DropDownList过滤的主/从报表 09.跨页面的主/从报表 10.使用 GridView和DetailView实现的主/从报表 11.基于数据的自定义格式化

  • 在ASP.NET 2.0中操作数据之五:声明参数

    导言 在上一章的教程中,我们看了GridView.DetailsView和FormView绑定到OjbectDataSource控件显示数据,ObjectDataSource调用了类ProductsBLL的GetProducts()方法.方法GetProducts()返回一个有Northwind数据库的Products表的所有记录组成的强类型数据表.类ProductsBLL还包含了其它返回部分数据的方法:GetProductByProductID(productID),GetProductsBy

  • 在ASP.NET 2.0中操作数据之三:创建母版页和站点导航

    导言 通常,用户友好的个性化站点都有着一致的,站点统一的页面布局和导航体系.Asp.net 2.0引入的两个新特性给我们在统一站点的页面布局和站点导航上提供了简单而有效的工具,它们是母板页和站点导航.母板页允许开发者创建统一的站点模板和指定的可编辑区域.这样,aspx页面只需要给模板页中指定的可编辑区域提供填充内容就可以了,所有在母板页中定义的其他标记将出现在所有使用了该母板页的aspx页面中.这种模式允许开发者可以统一的管理和定义站点的页面布局,因此可以容易的得到拥有统一的视觉和感觉的页面并且

  • 在ASP.NET 2.0中操作数据之四:使用ObjectDataSource展现数据

    在完成了应用程序架构和页面的设计后,我们可以开始探讨如何实现多种多样的普通数据到报表展现的任务.前面我们已经了解到如何在从数据访问层和业务逻辑层绑定数据到ASP.NET页面上的数据控件.在ASP.NET 1.x应用程序中,通过对数据控件的DataSource属性赋值然后调用控件的DataBind()方法从而实现数据展现的方式在ASP.NET 2.0应用程序中可以继续使用.然而,ASP.NET 2.0的数据源控件提供了一种新的方式,使用这些控件可以让你轻松从上文中创建的业务逻辑层中进行数据绑定,甚

  • 在ASP.NET 2.0中操作数据之一:创建一个数据访问层

    导言 作为web开发人员,我们的生活围绕着数据操作.我们建立数据库来存储数据,写编码来访问和修改数据,设计网页来采集和汇总数据.本文是研究在ASP.NET 2.0中实现这些常见的数据访问模式之技术的长篇系列教程的第一篇.我们将从创建一个软件框架开始,这个框架的组成部分包括一个使用强类型的DataSet的数据访问层(DAL),一个实施用户定义的业务规则的业务逻辑层(BLL),以及一个由共享页面布局的ASP.NET网页组成的表现层.在打下这个后端的基础工作之后,我们将开始转向报表,示范如何显示,汇总

随机推荐