手机版

ASP.NET 2.0中的运行数据XV:在GridView的页脚显示统计信息

时间:2021-11-01 来源:互联网 编辑:宝哥软件园 浏览:

介绍

用户除了知道产品的单价、库存和订单数量,并按等级进行排序外,还可能对统计信息感兴趣,如平均价格、库存总额等。这些统计数据通常显示在报告底部的统计行中。GridView控件可以包含一个页脚行,我们可以通过编程将统计数据插入其单元格。这项任务给我们带来了以下三个挑战:

1.配置GridView以显示其页脚行。

2.确定统计数据。也就是说,我们应该如何计算平均价格和总库存?

3.将统计数据插入页脚行的相应单元格。

在本教程中,我们将看到如何克服这些挑战。此外,我们将创建一个包含列出所有类别的下拉框的页面,并选择一个类别以在GridView中显示该类别中的产品。GridView包含一个页脚行,用于显示此类产品的平均价格、总库存和总订单。

//files.jb51.net/file_images/article/201605/2016050617181278.png

图1:统计数据显示在GridView的页脚行。

由于从类别到产品都有一个主/从接口,因此本节的所有内容都基于上一节“使用DropDownList进行主/从过滤”中讨论的概念。如果你还没有读过那一节,最好在继续这一节之前先读一读。

第1部分:添加类别下拉框和产品网格视图。

在向GridView添加页脚行之前,让我们简单地创建一个主/从报表。完成第一步后,我们可以看看如何添加统计数据。

首先在CustomFormatting文件夹中打开SummaryDataInFooter.aspx页面。添加一个DropDownList控件,并将其标识设置为类别。然后,在这个DropDownList的智能标记上单击“选择数据源”,添加一个新的ObjectDataSource控件,该控件调用CategoriesBLL类的GetCategories()方法,并命名这个objectdata Source categoriesdata Source。

//files.jb51.net/file_images/article/201605/2016050617181579.png

图2:添加一个名为CategoriesDataSource的新ObjectDataSource控件。

//files.jb51.net/file_images/article/201605/2016050617181580.png

图3:让这个ObjectDataSource控件调用CategoriesBLL类的GetCategories()方法。

配置好ObjectDataSource后,向导会将我们返回到DropDownList的数据源配置向导,在这里我们可以指定需要显示哪些字段,哪些字段应该作为DropDownList的ListItem的值。我们使用CategoryName字段进行显示,使用CategoryID作为值。

//files.jb51.net/file_images/article/201605/2016050617181981.png

图4: CategoryName和CategoryID分别用作ListItem的文本和值。

现在,我们有一个DropDownList,它可以列出系统中的类别。现在我们需要添加一个GridView,它根据所选的类别列出产品。然而,在此之前,让我们花点时间勾选DropDownList智能标记中的“启用自动回邮”复选框。正如我们在上一节“使用DropDownList进行主/从过滤”中所讨论的,在将DropDownList的AutoPostBack属性设置为true后,只要DropDownList的值发生变化,页面就会回发。这样,可以刷新GridView以显示新选择的类别的产品。如果AutoPostBack属性设置为false(默认值),更改类别不会导致回发,因此无法刷新产品列表。

//files.jb51.net/file_images/article/201605/2016050617181982.png

图5:勾选DropDownList智能标记中的复选框“启用自动回发”。

向页面添加GridView控件,以便可以根据所选类别显示产品。将此网格视图的标识设置为产品类别,并将其绑定到名为产品类别数据源的新对象数据源。

//files.jb51.net/file_images/article/201605/2016050617181983.png

图6:添加一个名为ProductsInCategoryDataSource的新对象数据源。

配置此ObjectDataSource,使其调用ProductsBLL类的getProductBycategoryid(categoryid)方法。

//files.jb51.net/file_images/article/201605/2016050617181984.png

图7:让这个ObjectDataSource调用getproductbycategoryid(Categoryid)方法。

getproductbycategoryid(categoryid)方法需要一个参数,因此在向导的最后一步,我们可以指定参数值的数据源。要根据所选类别显示产品,应从类别下拉框中获取此参数。

//files.jb51.net/file_images/article/201605/2016050617181985.png

图8:从Catefories下拉框中获取categoryID参数。

完成向导后,该GridView将包含对应于产品每个属性的BoundField。让我们清理这些边界字段,并保留显示产品名称、单价、单位库存和单位订单。然后,您可以随意向剩余的边界字段添加一些字段级设置(例如,将单价格式化为货币)。进行这些更改后,该GridView的声明标记应该如下所示:

asp: GridView ID=' Product In category ' runat=' server ' AutoGenerateColumns=' False ' DataKeyNames=' Product ID ' data sourceid=' Product In category data source ' EnableViewState=' False '列asp3360 boundfield data field=' Product name ' header text=' Product ' sort expression=' Product name '/asp: boundfield data field=' UnitPrice ' data formatstring=' { 03: c } ' header text='

//files.jb51.net/file_images/article/201605/2016050617181986.png

图9:现在的效果(译者注:估计原文有错误,写成图8。这里的原文是“图9:从所选类别dropdownlist获取categoryid参数值”,图8的原文是“图8:从所选类别dropdownlist获取categoryid参数值”)。

第二步:在GridView中显示页脚。

GridView控件可以显示页眉和页脚行。是否显示这些行分别取决于显示页眉和显示页脚属性。默认情况下,显示页眉值为真,显示页脚值为假。要显示页脚行,我们只需将ShowFooter属性设置为true。

//files.jb51.net/file_images/article/201605/2016050617182087.png

图10:将GridView的ShowFooter属性设置为true。

GridView中定义的每个字段在页脚行中都有相应的单元格,但默认情况下这些单元格是空的。花点时间在浏览器中查看我们的结果。由于我们将GridView的ShowFooter属性设置为true,因此GridView现在包含一个空的页脚行。

//files.jb51.net/file_images/article/201605/2016050617182088.png

图11: GridView现在有一个页脚行。

图11中的页脚行不明显,因为它的背景是白色的。让我们在Styles.css中创建一个名为footers style的css类,并使用它来指定一个深红色的背景,并在DataWebControls主题中配置Skin文件GridView.skin,将这个CSS类分配给这个GridView的footers style的CSS类属性。如果您需要查看皮肤和主题,请参考“使用对象数据源显示数据”。

首先将以下CSS类添加到Styles.css中:footers style { background-color : # a33;颜色:白色;text-align:右侧;} FooterStyle与HeaderStyle类是同一个CSS类,只是HeaderStyle的背景颜色更深,文本以粗体显示。此外,页脚文本右对齐,而页眉文本居中。然后,为了将这个CssClass与每个GridView页脚相关联,请在DataWebControls主题中打开GridView.skin文件,并设置FooterStyle的CSS class属性。添加之后,文件的标记代码应该如下所示:

ASP : GridView runat=' server ' CSS class=' DataWebControlStyle ' AlternatingRowStyle CSS class=' AlternatingRowStyle '/row style CSS class=' row style '/header style CSS class=' header style '/footers style CSS class=' footers style '/selectedrowstyle CSS class=' selectedrowstyle '/ASP 3360 GridView如下图所示,此更改使页脚显示清晰。

//files.jb51.net/file_images/article/201605/2016050617182089.png

图12:GridView的页脚现在有了红色的背景色。

第三步:计算统计数据。

显示完GridView的页脚后,我们面临的下一个挑战是如何计算统计数据。有两种方法可以计算统计数据:

1.通过一个SQL查询——,我们可以向数据库发送一个额外的查询来计算特定类别的统计信息。SQL包含一系列聚合函数,GROUP BY子句指定了哪些数据应该用于统计。以下SQL查询将返回我们需要的信息:

从产品中选择类别编号、AVG(单位价格)、总和(单位库存)、总和(单位订单)其中类别编号=类别编号按类别分组

当然,您可能不喜欢在SummaryDataInFooter.aspx页面中直接执行此查询,而是希望在ProductsTableAdapter和ProductsBLL中创建一个方法来完成此操作。

2.由于此信息已添加到GridView中,因此可以直接计算——。如“基于数据的自定义格式”中所述,在GridView的数据绑定之后,GridView的RowDataBound事件处理方法将在添加每一行数据时执行一次。为这个事件创建一个事件处理方法后,我们可以保留一个累计的总值。最后一行数据绑定到DataGrid后,我们就有了一个总值和计算平均值所需的信息。

一般来说,我更喜欢第二种方法,因为它节省了对数据库的往返,要达到这种效果,需要在数据访问层和业务逻辑层实现统计功能,但话说回来,其实这两种方法都可以。在本教程中,让我们使用第二种方法,并使用RowDataBound事件处理方法来记录这个累计总数。

为GridView创建新的RowDataBound事件处理方法。您可以在设计器中选择GridView,在属性窗口中单击带有闪电符号的图标,找到RowDataBound事件并双击它。这样,一个名为productsincategory _ rowdatabound的新事件处理方法将被添加到SummaryDataInFooter.aspx页面的后代码类中。

protected void product In integrary _ row data bound(对象发送方,gridviewroweventargs e) {}为了保持累计总数,我们需要在此事件处理方法之外定义一些变量。创建以下4个页面级变量:

_总单价,类型为十进制。

int类型的totalnnonnullunitpricecount。

totalunitsinstock,类型为int。

totalunitsonorder _ int类型。

然后,在RowDataBound事件处理方法中编写一些代码,这样每个数据行都可以增加这些变量的值。

//类范围,运行总变量.decimal _ totalUnitPrice=0 int _ totalnonullunitpricecount=0;int _ totalUnitsInStock=0;int _ totalUnitsOnOrder=0;受保护的integrary _ RowDataBond中的void乘积(对象发送方,GridView Roweventargs e){ if(e . row。行类型==数据控制行类型.DataRow) { //通过行数据项目属性北风引用产品行.产品行产品=(北风。产品行()((系统。数据行视图)。划;//递增运行总数(如果不为空!)if(!产品. IsUnitPriceNull()){ _ TotalUnitPrice=product .单价;_ totalNonNullUnitPriceCount } if(!产品isunitsonstocknull())_ totalUnitsInStock=product .UnitsInStockif(!产品isunitsonoordernull())_ totalUnitsOnOrder=product .UnitsOnOrder}}在触发事件事件处理方法中,我们首先应该确保我们正在操作一个数据行。一旦确定了是这么回事,e.Row中那个刚刚绑定到GridViewRow对象的北风。产品行实例就可以赋值给产品变量了。接着,累积合计就被当前产品的相关值(当然了,我们还是应该要确保它们不会含有一个数据库空值)增加了。我们同时记录了累积的单价合计以及非空单价记录的条数,因为平均价格是这两个数的商。

第四步:在页脚中显示统计数据

计算了统计数据之后,最后一个步骤就是在显示数据表格(一种控件)的页脚上显示它了。同样,这个任务也可以通过触发事件事件处理方法来完成。回忆一下触发事件事件处理方法,它会在每一行绑定到显示数据表格(一种控件)的时候被触发,页脚行也不例外。因此,我们可以扩展我们的事件处理方法,让它可以通过如下的代码来在页脚行中显示数据:

受保护的integrary _ RowDataBond中的void乘积(对象发送方,GridView Roweventargs e){ if(e . row。行类型==数据控制行类型.DataRow){ 0.增加运行总数.} else if(例如row。行类型==数据控制行类型.页脚){ 0.在页脚显示汇总数据.}}因为页脚行是在所有的数据行都已经添加之后才添加到显示数据表格(一种控件)中的,所以我们可以相信在将统计数据显示在页脚中之前,累积合计值都已经计算完毕了。最后一步就是将这些值放到页脚的单元格中了。

要在页脚的特定单元格中显示文本,可以使用使用行单元格[索引]。文本=值,单元格的索引是从0开始的。下面的代码计算了平均价格(总的价格除以产品的数量)并将其与库存量和订货量一起显示到显示数据表格(一种控件)页脚的相应单元格中。

受保护的integrary _ RowDataBond中的void乘积(对象发送方,GridView Roweventargs e){ if(e . row。行类型==数据控制行类型.DataRow){ 0.输入运行总数/i.} else if(例如row。行类型==数据控制行类型.页脚){ //确定平均单价小数avgUnitPrice=_totalUnitPrice /(小数)_ totalnonullunitpricecount//在适当的单元格中显示汇总数据文本='平均值: ' avgUnitPrice .ToString(' c ');行单元格[2]。text=' total : ' _ total units in stock .ToString();行单元格[3]。text=' total : ' _ total unitsonorder .ToString();}}图十三展示了添加了这段代码之后这个报表的样子。注意ToString('c ')是如何让平均价格这个统计信息格式化成货币形式的。

//files.jb51.net/file_images/article/201605/2016050617182190.png

图十三:现在的效果(译者注:估计原文这里又弄错了,写得跟图十二的一样。这里的原文是图13:网格视图的页脚行现在有一个红色的背景色,图十二的一样。这里的原文是图13:网格视图的页脚行现在有一个红色的B的原文是"图12:网格视图的页脚行现在有一个红色的背景色")

总结

显示统计信息是常见的报表需求,GridView控件可以在页脚行中包含此类信息,这使得操作非常简单。当GridView的ShowFooter属性设置为true时,可以显示页脚行,并且可以通过RowDataBound事件处理方法在GridView的不同单元格中显示该信息。您可以再次查询数据库的数据,也可以在ASP.NET页面的后代码类中以编程方式计算这些统计信息。

本教程结束了我们对GridView、DetailsView和FormView控件的自定义格式的研究。在下面的教程中,我们将开始探索通过使用这些控件来添加、删除和修改操作。

编程快乐!

关于作者

斯科特米切尔,六本关于ASP/ASP的书的作者。NET,是4GuysFromRolla.com的创始人,自1998年以来一直使用微软的网络技术。Scott是一名独立的技术顾问、培训师和作家,最近完成了一部即将由Sams出版社出版的新作,24小时内精通ASP.NET 2.0。他的联系电子邮件是[emailprotected],也可以通过他的博客http://ScottOnWriting.NET联系到他。

版权声明:ASP.NET 2.0中的运行数据XV:在GridView的页脚显示统计信息是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。