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

 更新时间:2016年5月19日 22:52  点击:2682
在前面的指南中我们研究了如何显示一个简单的主/从报表, 该报表使用DropDownList和GridView控件, DropDownList填充类别,GridView显示选定类别的产品. 这类报表用于显示具有一对多关系的记录时非常合适, 同时它也可以很容易的被扩展以显示多个一对多关系的数据. 比如, 一个订单系统应该包含表示客户,订单和订单明细的表. 一个客户也许有多个订单,每个订单又包含多条订单项. 这样的数据可以使用两个DropDownList和一个GridView呈现给用户. 第一个DropDownList应该包含数据库中所有客户的列表, 第二个DropDownList的内容是选定客户的订单. GridView用于列出所选定订单的订单明细项.

Step 1: 创建DropDownList并使用类别数据填充

  我们的第一个目标是添加一个能够列出类别的DropDownList. 这些步骤在前面的指南中已经做详细的分析, 但为了保持本篇指南的完整性有必要在这里简单概括一下.

  打开Filtering文件夹中的MasterDetailsDetails.aspx, 在页面上添加一个DropDownList, 设置它的ID为Categories,然后单击智能标记上的 Configure Data Source链接. 在数据源配置向导中选择新增一个数据源.

图 1: 为DropDownList增加一个新的数据源

  当然, 新的数据源应该是ObjectDataSource. 把新的ObjectDataSource命名为CategoriesDataSource并且让他调用CategoriesBLL对象的GetCategories()方法

图 2: 选择使用CategoriesBLL类

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

  配置完ObjectDataSource后还需要指定要在DropDownList中显示的数据字段,以及作为数据项的值(value for the list item)的数据字段.我们指定CategoryName为要显示的列,指定CategoryID为数据项的值字段

图4: 指定DropDownList 显示CategoryName列并且使用CategoryID列作为数据项的值

  这时,我们就有了一个使用Categories表中的记录来填充的DropDownList控件. 当用户在DropDownList中选择一个新的类别时, 我们需要一次回发,这样可以刷新在第二步中我们要创建的产品DropDownList控件. 所以, categoriesDropDownList的智能标记上选中AutoPostBack选项.

图 5: 选中Categories DropDownList 的AutoPostBack

Step 2: 在第二个DropDownList 中显示选中类别的产品

  Categories DropDownList完成后, 下一步就需要一个显示属于选定类别的产品的DropDownList了. 要完成这个功能, 再增加一个DropDownList控件并命名为ProductsByCategory. 与Categories DropDownList一样, 为ProductsByCategory DropDownList创建一个新的ObjectDataSource并命名为ProductsByCategoryDataSource.

图 6: 为ProductsByCategory DropDownList添加新数据源

图7: 创建一个新的 ObjectDataSource 并命名为ProductsByCategoryDataSource

  由于ProductsByCategory DropDownList 需要显示属于选定类别的产品, 让ObjectDataSource 调用ProductsBLL对象的GetProductsByCategoryID(categoryID)方法.

图8: 选择使用ProductsBLL类

图9: 配置ObjectDataSource 使用GetProductsByCategoryID(categoryID)方法

  在向导的最后一步需要指定categoryID的值. 我们把Categories DropDownList的已选择的数据项项作为该参数值.

图10: 使用categoryID参数从Categories DropDownList接收值

  ObjectDataSource配置完成后, 剩下的就是指定DropDownList要显示的字段和作为值的字段了. 设置为显示ProductName并把ProductID做为值字段

图11: 指定 DropDownList数据项的文本和值使用的数据源字段

  ObjectDataSource 和ProductsByCategory DropDownList配置完成后页面上会有两个DropDownList: 第一个列出所有的类别,第二个列出属于选定类别的产品. 当用户在第一个DropDownList上选择了一个新的类别后, 将会发生一次回发(postback),第二个DropDownList将会重新绑定以显示属于新选定类别的产品. 图12 和图13显示了在浏览器中看到的MasterDetailsDetails.aspx页面.

图12: 第一次访问页面时Beverages 类别是选中的.

图13: 选择一个不同的类别时显示该类别的产品

图14: 激活productsByCategory DropDownList的 AutoPostBack属性

Step 3: 使用DetailsView 显示选中产品的详细信息

  最后一个步骤是在DetailsView中显示选中产品的详细信息. 要完成该功能, 添加一个DetailsView到页面上, 设置它的ID属性为ProductDetails, 给它创建一个新的ObjectDataSource. 配置ObjectDataSource使它通过ProductsBLL类的GetProductByProductID(productID)方法填充数据,使用ProductsByCategory DropDownList的已选择项的值作为productID参数的值.

图15: 选择使用ProductsBLL类

图16: 配置 ObjectDataSource 使用GetProductByProductID(productID)方法

图17: 使用ProductsByCategory DropDownList的值作为productID参数的值

  你可以选择在DetailsView显示的任何有效的字段. 我决定不显示ProductID, SupplierID, 和CategoryID字段并且对其余的字段重新排序及格式化.另外, 我去掉了DetailsView的Height和Width属性设置, 允许DetailsView可以扩展到需要的宽度, 这样比把它限制在指定的大小会更好的显示数据. 下面便是全部的标记性语言(markup)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<asp:DetailsView ID="ProductDetails" runat="server" AutoGenerateRows="False" DataKeyNames="ProductID"
 
DataSourceID="ObjectDataSource1" EnableViewState="False">
 
<Fields>
 
<asp:BoundField DataField="ProductName" HeaderText="Product" SortExpression="ProductName" />
 
<asp:BoundField DataField="CategoryName" HeaderText="Category" ReadOnly="True" SortExpression="CategoryName" />
 
<asp:BoundField DataField="SupplierName" HeaderText="Supplier" ReadOnly="True" SortExpression="SupplierName" />
 
<asp:BoundField DataField="QuantityPerUnit" HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
 
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" HeaderText="Price"
 
HtmlEncode="False" SortExpression="UnitPrice" />
 
<asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" SortExpression="Units In Stock" />
 
<asp:BoundField DataField="UnitsOnOrder" HeaderText="UnitsOnOrder" SortExpression="Units On Order" />
 
<asp:BoundField DataField="ReorderLevel" HeaderText="ReorderLevel" SortExpression="Reorder Level" />
 
<asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued" SortExpression="Discontinued" />
 
</Fields>
 
</asp:DetailsView>

  花点时间在浏览器中测试一下MasterDetailsDetails.aspx页面. 乍一看好像一切如预计的那样顺利, 但是却有一个小问题. 当你选择了一个新类别, ProductsByCategory DropDownList会更新显示选中类别的产品, 但是ProductDetails DetailsView还是显示上一个产品的信息. 当选择了一个选中类别的不同的产品时DetailsView应该被更新. 此外,如果你的测试足够彻底, 你将会发现如果你不断的选择新类别(比如在Categories DropDownList中选择Beverages,然后选择Condiments,然后是Confections)每个类别的选择都会使ProductDetails DetailsView被刷新.

  为了让这个问题更具体一些, 让我们看一个例子. 当你第一次访问该页面时, Beverages类别是选中的并且与之相关的产品在ProductsByCategory DropDownList中列出. Chai是当前选中的产品,他的详细信息显示在ProductDetails DetailsView中

图18: DetailsView显示了选中产品的详细信息

  如果你把类别选项Beverages 改成 Condiments, 便会发生一次回发, ProductsByCategory DropDownList会相应的更新, 但是DetailsView仍然会显示Chai的详细信息.

图19:上一次选择产品的详细信息仍然在显示

  在列表中选择一个产品会如预期地一样刷新DetailsView, 如果你改变了产品之后选择了一个新的类别, DetailsView又一次没有刷新. 然后如果你选择一个新类别而不是选择一个产品, DetailsView则会刷新. 究竟是怎么回事呢?

  这个问题是由页面生命周期的时间调度引发的. 当页面被请求时会经过一系列的处理后呈现出来. 这其中的一项处理便是ObjectDataSource控件检查他的SelectParameters值是否发生变化. 如果发生了变化, WEB控件绑定到ObjectDataSource的数据便会刷新显示. 比如, 当一个新类别被选中时, ProductsByCategoryDataSource ObjectDataSource发现它的参数值已经发生了变化,然后ProductsByCategory DropDownList就会重新绑定,获取所选中类别的产品.

  在这种情况下发生的该问题是由于在页面的生命周期中ObjectDataSources检查参数是否发生改变的动作是在关联的WEB控件重新绑定之前. 因此,当选择了一个新的类别ProductsByCategoryDataSource ObjectDataSource会检查到它的参数值发生了变化. 但是, ProductDetails DetailsView使用的ObjectDataSource并没有发生任何变化,因为ProductsByCategory DropDownList还没有重新绑定. 在稍后的生命周期中ProductsByCategory DropDownList重新绑定到它的ObjectDataSource,获取刚刚选中类别的产品. 当ProductsByCategory DropDownList的值发生变化的时候ProductDetails DetailsView的 ObjectDataSource已经完成了它的参数值检查工作. 因此, DetailsView还是显示先前的数据. 图20描述了这个交互的过程.

图20: T ProductDetails DetailsView的 ObjectDataSource的检查工作结束后ProductsByCategory DropDownList的值才改变.

  要解决这个问题,我们需要在ProductsByCategory DropDownList绑定后显式的重新绑定ProductDetails DetailsView. 我们可以在ProductsByCategory DropDownList的DataBound事件中调用ProductDetails DetailsView的DataBind()方法. 把下面的事件处理代码添加到MasterDetailsDetails.aspx页面的代码后置类:

?
1
2
3
4
5
6
protected void ProductsByCategory_DataBound(object sender, EventArgs e)
{
 
  ProductDetails.DataBind();
 
}

添加对ProductDetails DetailsView的DataBind()方法的显式调用后,就一切正常了. 图21高亮显示了该方法是如何解决这个问题的.

图21:在ProductsByCategory DropDownList的DataBound事件中ProductDetails DetailsView被显示的刷新.

  DropDownList控件是一个非常理想的用于主/从报表(主记录和从记录存在一对多关系)的用户接口元素(user interface element ). 在前面的教程中我们看到了如何使用单个DropDownList对选中的类别进行产品过滤. 在本教程中我们使用GridView代替了DropDownList做为产品列表, 使用DetailsView显示选中产品的详细信息. 本教程所讨论的概念可以很容易的扩展到包含多个一对多关系的数据模型, 比如客户,订单及订单项. 通常,在一对多的关系中你总是可以使用DropDownList 来表示"主"实体(一对多中的一,主/从关系的主记录)

脚本http://www.csdn123.com

[!--infotagslink--]

相关文章

  • ASP.NET购物车实现过程详解

    这篇文章主要为大家详细介绍了ASP.NET购物车的实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
  • 图解PHP使用Zend Guard 6.0加密方法教程

    有时为了网站安全和版权问题,会对自己写的php源码进行加密,在php加密技术上最常用的是zend公司的zend guard 加密软件,现在我们来图文讲解一下。 下面就简单说说如何...2016-11-25
  • ps怎么使用HSL面板

    ps软件是现在很多人都会使用到的,HSL面板在ps软件中又有着非常独特的作用。这次文章就给大家介绍下ps怎么使用HSL面板,还不知道使用方法的下面一起来看看。 &#8195;...2017-07-06
  • 在ASP.NET 2.0中操作数据之七十二:调试存储过程

    在开发过程中,使用Visual Studio的断点调试功能可以很方便帮我们调试发现程序存在的错误,同样Visual Studio也支持对SQL Server里面的存储过程进行调试,下面就让我们看看具体的调试方法。...2021-09-22
  • Plesk控制面板新手使用手册总结

    许多的朋友对于Plesk控制面板应用不是非常的了解特别是英文版的Plesk控制面板,在这里小编整理了一些关于Plesk控制面板常用的使用方案整理,具体如下。 本文基于Linu...2016-10-10
  • 使用insertAfter()方法在现有元素后添加一个新元素

    复制代码 代码如下: //在现有元素后添加一个新元素 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement){ parent.appendChild(newEl...2014-05-31
  • 使用percona-toolkit操作MySQL的实用命令小结

    1.pt-archiver 功能介绍: 将mysql数据库中表的记录归档到另外一个表或者文件 用法介绍: pt-archiver [OPTION...] --source DSN --where WHERE 这个工具只是归档旧的数据,不会对线上数据的OLTP查询造成太大影响,你可以将...2015-11-24
  • 使用GruntJS构建Web程序之构建篇

    大概有如下步骤 新建项目Bejs 新建文件package.json 新建文件Gruntfile.js 命令行执行grunt任务 一、新建项目Bejs源码放在src下,该目录有两个js文件,selector.js和ajax.js。编译后代码放在dest,这个grunt会...2014-06-07
  • 如何使用php脚本给html中引用的js和css路径打上版本号

    在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、...2015-11-24
  • jQuery 1.9使用$.support替代$.browser的使用方法

    jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9。 如果要全面支持 IE,并混合...2014-05-31
  • 安装和使用percona-toolkit来辅助操作MySQL的基本教程

    一、percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 检查master和slave数据的一致性 有效地对记录进行归档 查找重复的索...2015-11-24
  • MySQL日志分析软件mysqlsla的安装和使用教程

    一、下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz--19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gzResolving hackmysql.com... 64.13.232.157Conn...2015-11-24
  • php语言中使用json的技巧及json的实现代码详解

    目前,JSON已经成为最流行的数据交换格式之一,各大网站的API几乎都支持它。我写过一篇《数据类型和JSON格式》,探讨它的设计思想。今天,我想总结一下PHP语言对它的支持,这是开发互联网应用程序(特别是编写API)必须了解的知识...2015-10-30
  • PHP实现无限级分类(不使用递归)

    无限级分类在开发中经常使用,例如:部门结构、文章分类。无限级分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式; 查找分类A下面所有分类包含的文章。1.实现原理 几种常见的实现方法,各有利弊。其中...2015-10-23
  • C#注释的一些使用方法浅谈

    C#注释的一些使用方法浅谈,需要的朋友可以参考一下...2020-06-25
  • php类的使用实例教程

    php类的使用实例教程 <?php /** * Class program for yinghua05-2 * designer :songsong */ class Template { var $tpl_vars; var $tpl_path; var $_deb...2016-11-25
  • 双冒号 ::在PHP中的使用情况

    前几天在百度知道里面看到有人问PHP中双冒号::的用法,当时给他的回答比较简洁因为手机打字不大方便!今天突然想起来,所以在这里总结一下我遇到的双冒号::在PHP中使用的情况!双冒号操作符即作用域限定操作符Scope Resoluti...2015-11-08
  • ASP.NET Core根据环境变量支持多个 appsettings.json配置文件

    这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 记一次EFCore类型转换错误及解决方案

    这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
  • PHP mysql与mysqli事务使用说明 分享

    mysqli封装了诸如事务等一些高级操作,同时封装了DB操作过程中的很多可用的方法。应用比较多的地方是 mysqli的事务。...2013-10-02