音效素材网提供各类素材,打造精品素材网站!

站内导航 站长工具 投稿中心 手机访问

音效素材

ASP.NET 2.0中的数据操作之八:使用两个DropDownList过滤的主/从报表
日期:2021-09-07 22:12:57   来源:脚本之家

导言

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

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

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

//img.jbzj.com/file_images/article/201605/2016050409191815.png

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

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

//img.jbzj.com/file_images/article/201605/2016050409192116.png

图 2: 选择使用CategoriesBLL类

//img.jbzj.com/file_images/article/201605/2016050409192117.png

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

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

//img.jbzj.com/file_images/article/201605/2016050409192218.png

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

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

//img.jbzj.com/file_images/article/201605/2016050409192219.png

图 5: 选中Categories DropDownList 的AutoPostBack

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

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

//img.jbzj.com/file_images/article/201605/2016050409192220.png

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

//img.jbzj.com/file_images/article/201605/2016050409192221.png

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

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

//img.jbzj.com/file_images/article/201605/2016050409192222.png

图8: 选择使用ProductsBLL类

//img.jbzj.com/file_images/article/201605/2016050409192323.png

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

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

//img.jbzj.com/file_images/article/201605/2016050409192324.png

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

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

//img.jbzj.com/file_images/article/201605/2016050409192325.png

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

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

//img.jbzj.com/file_images/article/201605/2016050409192326.png

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

//img.jbzj.com/file_images/article/201605/2016050409192327.png

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

//img.jbzj.com/file_images/article/201605/2016050409192328.png

图14: 激活productsByCategory DropDownList的 AutoPostBack属性

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

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

//img.jbzj.com/file_images/article/201605/2016050409192329.png

图15: 选择使用ProductsBLL类

//img.jbzj.com/file_images/article/201605/2016050409192430.png

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

//img.jbzj.com/file_images/article/201605/2016050409192431.png

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

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

<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.

//img.jbzj.com/file_images/article/201605/2016050409192432.png

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

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

//img.jbzj.com/file_images/article/201605/2016050409193133.png

图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描述了这个交互的过程.

//img.jbzj.com/file_images/article/201605/2016050409193134.png

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

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

protected void ProductsByCategory_DataBound(object sender, EventArgs e)
{

 ProductDetails.DataBind();

}

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

//img.jbzj.com/file_images/article/201605/2016050409193135.png

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

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

祝编程愉快!

作者简介

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

    您感兴趣的教程

    在docker中安装mysql详解

    本篇文章主要介绍了在docker中安装mysql详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编...

    详解 安装 docker mysql

    win10中文输入法仅在桌面显示怎么办?

    win10中文输入法仅在桌面显示怎么办?

    win10系统使用搜狗,QQ输入法只有在显示桌面的时候才出来,在使用其他程序输入框里面却只能输入字母数字,win10中...

    win10 中文输入法

    一分钟掌握linux系统目录结构

    这篇文章主要介绍了linux系统目录结构,通过结构图和多张表格了解linux系统目录结构,感兴趣的小伙伴们可以参考一...

    结构 目录 系统 linux

    PHP程序员玩转Linux系列 Linux和Windows安装

    这篇文章主要为大家详细介绍了PHP程序员玩转Linux系列文章,Linux和Windows安装nginx教程,具有一定的参考价值,感兴趣...

    玩转 程序员 安装 系列 PHP

    win10怎么安装杜比音效Doby V4.1 win10安装杜

    第四代杜比®家庭影院®技术包含了一整套协同工作的技术,让PC 发出清晰的环绕声同时第四代杜比家庭影院技术...

    win10杜比音效

    纯CSS实现iOS风格打开关闭选择框功能

    这篇文章主要介绍了纯CSS实现iOS风格打开关闭选择框,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作...

    css ios c

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的办法

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的

    Win7给电脑C盘扩容的办法大家知道吗?当系统分区C盘空间不足时,就需要给它扩容了,如果不管,C盘没有足够的空间...

    Win7 C盘 扩容

    百度推广竞品词的投放策略

    SEM是基于关键词搜索的营销活动。作为推广人员,我们所做的工作,就是打理成千上万的关键词,关注它们的质量度...

    百度推广 竞品词

    Visual Studio Code(vscode) git的使用教程

    这篇文章主要介绍了详解Visual Studio Code(vscode) git的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...

    教程 Studio Visual Code git

    七牛云储存创始人分享七牛的创立故事与

    这篇文章主要介绍了七牛云储存创始人分享七牛的创立故事与对Go语言的应用,七牛选用Go语言这门新兴的编程语言进行...

    七牛 Go语言

    Win10预览版Mobile 10547即将发布 9月19日上午

    微软副总裁Gabriel Aul的Twitter透露了 Win10 Mobile预览版10536即将发布,他表示该版本已进入内部慢速版阶段,发布时间目...

    Win10 预览版

    HTML标签meta总结,HTML5 head meta 属性整理

    移动前端开发中添加一些webkit专属的HTML5头部标签,帮助浏览器更好解析HTML代码,更好地将移动web前端页面表现出来...

    移动端html5模拟长按事件的实现方法

    这篇文章主要介绍了移动端html5模拟长按事件的实现方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家...

    移动端 html5 长按

    HTML常用meta大全(推荐)

    这篇文章主要介绍了HTML常用meta大全(推荐),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    cdr怎么把图片转换成位图? cdr图片转换为位图的教程

    cdr怎么把图片转换成位图? cdr图片转换为

    cdr怎么把图片转换成位图?cdr中插入的图片想要转换成位图,该怎么转换呢?下面我们就来看看cdr图片转换为位图的...

    cdr 图片 位图

    win10系统怎么录屏?win10系统自带录屏详细教程

    win10系统怎么录屏?win10系统自带录屏详细

    当我们是使用win10系统的时候,想要录制电脑上的画面,这时候有人会想到下个第三方软件,其实可以用电脑上的自带...

    win10 系统自带录屏 详细教程

    + 更多教程 +
    ASP编程JSP编程PHP编程.NET编程python编程