三十五使用Repeater和DataList单页面实现主从报表.docx
- 文档编号:3619437
- 上传时间:2022-11-24
- 格式:DOCX
- 页数:20
- 大小:354.19KB
三十五使用Repeater和DataList单页面实现主从报表.docx
《三十五使用Repeater和DataList单页面实现主从报表.docx》由会员分享,可在线阅读,更多相关《三十五使用Repeater和DataList单页面实现主从报表.docx(20页珍藏版)》请在冰豆网上搜索。
三十五使用Repeater和DataList单页面实现主从报表
在ASP.NET2.0中操作数据之三十五:
使用Repeater和DataList单页面实现主/从报表
作者:
heker2007字体:
[增加 减小]类型:
转载时间:
2016-05-10 我要评论
前面已经介绍了ASP.NET2.0中如何使用两个页面实现主/从报表,本文主要讲解,如何使用一个单独页面实现主/从报表。
导言
在前面一章里我们学习了如何用两个页分别显示主/从信息。
在“主”页里我们用Repeater来显示category。
每个category的name都是一个链到“从”页的hyperlink。
在从页里用一个两列的DataList显示选中的category下的product。
本章我们将还是使用单页,在左边显示category列表,category的名字用LinkButton显示。
点击其中一个时页面postback,在右边以两列的DataList显示出相关的product。
除了名字外,左边的Repeater还会显示与该category相关联的product总数。
(见图1)
图1:
Category的Name和Product总数显示在左边
第一步:
在页面左部显示一个Repeater
本章我们将在左边显示category,右表显示它关联的product。
web页的内容可以使用标准HTML元素或者CSS来定位。
到目前为止我们都是使用CSS来定位。
在母板页和站点导航一章里我们使用绝对定位来创建导航时,为导航列表和内容之间指定了明确的距离。
当然CSS也可以用来对两个元素的位置进行调整。
打开DataListRepeaterFiltering文件夹下的CategoriesAndProducts.aspx页,添加一个Repeater和DataList.ID分别设置为Categories和CategoryProducts。
然后到源视图里将它们分别放到
也就是说在Repeater后面加一个闭合的
现在你的代码看起来应该和下面差不多:
?
1
2
3
4
5
6
7
8
RepeaterID="Categories"runat="server">
Repeater>
DataListID="CategoryProducts"runat="server">
DataList>
我们需要使用float属性来将Repeater放到DataList左边,见下面代码:
?
1
2
3
4
5
6
Repeater
DataList
float:
left将第一个
width和padding-right指定了第一个
更多的floating元素信息请参考Floatutorial.我们在Styles.css里创建一个新的CSS类,名为Floatleft(而不是直接在
的样式里设置):
?
1
2
3
4
5
6
.FloatLeft
{
float:
left;
width:
33%;
padding-right:
10px;
}
然后我们用 left">替换掉。 完成以上所讲的内容后,切换到设计视图。 你应该看到Repeater已经在DataList左边了(由于还没有配置数据源或模板,这两个控件都是灰的)。 图2: 调整完位置后的页面 第二步: 获取每个Category关联的Products总数 完成了样式设置后,我们现在来将category数据绑定到Repeater。 如图1所示,除了category名字外,我们需要显示和它关联的product总数,为了获取这个信息我们可以: 在ASP.NETpage的code-behind里获取这个信息.根据给定的categoryID我们可以通过ProductsBLL类的GetProductsByCategoryID(categoryID)方法来获取关联的product总数。 这个方法返回一个ProductsDataTable对象,它的Count属性表示了我们需要知道的信息。 我们可以为Repeater创建一个ItemDataBoundeventhandler,在每个category绑定到Repeater时调用这个方法然后将总数输出。 在DataSet里更新CategoriesDataTable添加一个NumberOfProducts列.我们可以更新CategoriesDataTable的GetCategories()方法来包含这个信息或者保留这个方法,再创建一个新的名为GetCategoriesAndNumberOfProducts()方法。 我们来看看这两种方法。 第一种写起来更简单,因为我们不需要更新DAL。 但是它需要和数据库更多的连接。 在ItemDataBoundeventhandler里调用GetProductsByCategoryID(categoryID)方法又增加了一次数据库连接(这在每个category绑定时会发生一次)。 这时一共会有N+1次对数据库的请求(N为Repeater里显示的category的总数)。 而第二种方法product总数从GetCategories()(或GetCategoriesAndNumberOfProducts())方法返回,这样只请求一次数据库就可以了。 在ItemDataBoundEventHandler里获取Products总数 在ItemDataBoundeventhandler里获取product总数不需要修改DAL。 只需要直接修改CategoriesAndProducts.aspx页。 通过Repeater的智能标签添加一个新的名为CategoriesDataSource的ObjectDataSource。 使用CategoriesBLL类的GetCategories()方法配置它。 图3: 配置ObjectDataSource Repeater里的每个Category都是可点的,而且在点了之后,CategoryProductsDataList会显示那些相关的product。 我们可以将每个category设为hyperlink,链到本页(CategoriesAndProducts.aspx),通过querystring为CategoryID赋值。 这种方法的好处是,特定category的product可以通为搜索建立索引和书签。 我们也可以将每个category设为LinkButton,在本章我们使用这个方法。 LinkButton看起来象一个hyperlink,但是点击后会产生一个postback。 DataList的ObjectDataSource会刷新以显示选中category相关联的product。 在本章使用hyperlink更合理。 然而在别的情况下可以使用LinkButton会好一点。 虽然是这样,我们在这里也使用LinkButton。 我们将会看到,使用LinkButton会有一些使用hyperlink时碰不到的挑战。 因此我们可以学习更好学习它,以便以后使用。 注意: 如果你使用HyperLink或来代替LinkButton来重复练习一次本章的内容,是最好不过了。 下面的标记语言是Repeater和ObjectDataSource的,注意Repeater的template将每个item表示为LinkButton。 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 RepeaterID="Categories"runat="server"DataSourceID="CategoriesDataSource"> LinkButtonrunat="server"ID="ViewCategory"/>
Repeater>
ObjectDataSourceID="CategoriesDataSource"runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetCategories"TypeName="CategoriesBLL">
ObjectDataSource>
注意:
在本章Repeater的viewstate必须开启(Repeater的声明语法里的EnableViewState="False")。
在第三步我们将为ItemCommand事件创建一个eventhandler,在它里面我们要更新DataList的ObjectDataSource的SeleceParameters集合。
如果viewstate被禁用的话Repeater的ItemCommand不会被激发。
想了解具体的原因和更多的信息请参考AStumperofanASP.NETQuestion和itssolution。
ID为ViewCategory的LinkButton还没有设置Text属性。
如果我们只需要显示category名字,我们可以通过绑定语法象下面这样来直接设置:
?
1
2
LinkButtonrunat="server"ID="ViewCategory" Text='<%#Eval("CategoryName")%>'/> 然而在这里我们需要显示的是category的name和proudct的总数。 见下面的代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 protectedvoidCategories_ItemDataBound(objectsender,RepeaterItemEventArgse) { //Makesurewe'reworkingwithadataitem... if(e.Item.ItemType==ListItemType.Item|| e.Item.ItemType==ListItemType.AlternatingItem) { //ReferencetheCategoriesRowinstanceboundtothisRepeaterItem Northwind.CategoriesRowcategory= (Northwind.CategoriesRow)((System.Data.DataRowView)e.Item.DataItem).Row; //Determinehowmanyproductsareinthiscategory NorthwindTableAdapters.ProductsTableAdapterproductsAPI= newNorthwindTableAdapters.ProductsTableAdapter(); intproductCount= productsAPI.GetProductsByCategoryID(category.CategoryID).Count; //ReferencetheViewCategoryLinkButtonandsetitsTextproperty LinkButtonViewCategory=(LinkButton)e.Item.FindControl("ViewCategory"); ViewCategory.Text= string.Format("{0}({1: N0})",category.CategoryName,productCount); } } 我们首先要确保我们处理的是dataitem(ItemType为Item或AlternatingItem)然后引用刚刚绑定到当前RepeaterItem的CategoriesRow。 然后调用GetCategoriesByProductID(categoryID)方法,通过Count属性获取返回的记录条数。 最后将ItemTemplate里的ViewCategoryLinkButton的Text属性设为"CategoryName(NumberOfProductsInCategory)"。 注意: 我们也可以在ASP.NET页的code-behind里写一个格式化功能,接收CategoryName和CategoryID的值,返回CategoryName和product总数的连接字符串。 然后将结果直接赋给LinkButton的Text属性,而不需要处理itemDataBound事件。 更多的格式化功能信息参考在GridView控件中使用TemplateField和格式化DataList和Repeater的数据。 添加完eventhandler后,在浏览器里看看页面。 见图4。 图4: 显示每个Category的Name和Products总数 更新CategoriesDataTable和CategoriesTableAdpter来包含每个Category的Product总数除了在每个category绑定到Repeater时获取product总数外,我们还可以修改DAL里CategoriesDataTable和CategoriesTableAdapter来包含这个信息.我们在CategoriesDataTable里加一列.打开App_Code/DAL/Northwind.xsd,右键点DataTable,选择Add/Column.见图5. 图5: 为CategoriesaDataSource增加一个新列 这样会添加一个名为Column1的列,你可以很方便的修改它的名字.将它重命名为NumberOfProducts.然后我们需要配置这列的属性.点这个列,来到属性窗口.将DataType从System.String修改为System.Int32.将ReadOnly属性设为True.见图6. 图6: 设置新列的属性 现在CategoriesDataTable里已经包含了NumberOfProducts列,但它的值还没有设置.我们可以修改GetCategories()方法,当每次获取category信息的时候返回它的信息.在这里由于只是本章用到了这个数据,我们来创建一个新的名为GetCategoriesAndNumberOfProducts().右键点CategoriesTableAdapter,选择NewQuery.会出现TableAdapterQuery配置向导.选择SQLstatement. 图7: 选择SQLStatement 图8: SQLStatement返回行数 下一步需要我们写sql语句.下面的语句返回每个category的CategoryID,CategoryName,Description和相关product的总数: ? 1 2 3 4 SELECTCategoryID,CategoryName,Description, (SELECTCOUNT(*)FROMProductspWHEREp.CategoryID=c.CategoryID) asNumberOfProducts FROMCategoriesc 图9: 使用的sql语句 注意计算product总数的子查询的别名为NumberOfProducts.它和CategoriesDataTable的NumberOfProducts列关联.最后一步是写方法的名字.分别为FillaDataTable和ReturnaDataTable命名为FillWithNumberOfProducts和GetCategoriesAndNumberOfProducts. 图10: 为新的TableAdapter的方法命名 现在DAL已经修改完了.由于我们所有展现层,BLL,DAL是逐层调用,所以我们需要在CategoriesBLL类的添加相应的GetCategoriesAndNumberOfProducts方法. ? 1 2 3 4 5 6 [System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Select,false)] publicNorthwind.CategoriesDataTableGetCategoriesAndNumberOfProducts() { returnAdapter.GetCategoriesAndNumberOfProducts(); } 完成DAL和BLL后,我们来将数据绑定到CategoriesRepeater.如果在"在ItemDataBoundEventHandler里获取Products总数"那部分里你已经为Repeater创建了ObjectDataSource,删掉它,然后去掉Repeater的DataSourceID属性,同样去掉ItemDataBound事件.Repeater现在回到了初始状态,添加一个名为CategoriesDataSource的ObjectDataSource.使用CategoriesBLL类的GetCategoriesAndNumberOfProducts()方法来配置它.见图11. 图11: 配置ObjectDataSource 然后修改ItemTemplate,使用数据绑定语法来将CategoryName和NumberOfProducts字段绑定到LinkButton的Text属性.完整的标记语言如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 RepeaterID="Categories"runat="server"DataSourceID="CategoriesDataSource"> LinkButtonrunat="server"ID="ViewCategory" Text='<%#String.Format("{0}({1: N0})",_ Eval("CategoryName"),Eval("NumberOfProducts"))%>'/>
Repeater>
ObjectDataSourceID="CategoriesDataSource"runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetCategoriesAndNumberOfProducts"TypeName="CategoriesBLL">
ObjectDataSource>
使用这种方法的页面看起来和前面一种方法一样(见图4).
第三步:
显示选中的Category关联的Products
现在category和product总数的部分已经完成.Repeater将每个category显示为LinkButton,当点击时产生postback,这时我们需要将那些关联的product在CategoryProductsDataList里显示出来.
现在我们面临的一个挑战是如何将特定category下的product在DataList里显示出拉一.在使用GridView和DetailView实现的主/从报表一章里我们学习了创建一个GirdView,当选择它的一行时将"从"信息在本页的DetailsView里显示出来.GridView的ObjectDataSource用ProductsBLL的GetProducts()返回product信息.而DetailsView的ObjectDataSource用GetProductsByProductID(productID)返回选中的product信息.productID参数通过GirdView的SelectedValue属性来提供.不幸的是,Repeater没有SelectedValue属性.
注意:
这是我们在Repeater里使用LinkButton的其中一个挑战.如果我们使用hperlink,可以通过querystring来传递CategoryID.在我们解决这个问题前,首先将ObjectDataSource绑定到DataList,然后指定ItemTemplate.从DataList的智能标签添加一个名为CategoryProductsDataSource的ObjectDataSource,并使用ProductsBLL类的GetProductsByCategoryID(cateogryID)配置它.由于此DataList只提供只读功能,因此在INSERT,UPDATE,DELETE标签里选择None.
图12:
配置ObjectDataSource
由于GetProductsByCategoryID(categoryID)方法需要一个输入参数,向导会要求我们指定参数源.我们使用GridView或DataList列出categories时,可以将参数源设为Control,ControlID设为数据控件的ID.然而由于Repeater没有SelectedValue属性,所以不能用作参数源.你可以查看ControlID下拉列表,它里面只包含一个控件ID—CategoryProducts(DataList).
图13:
配置参数
配置完数据源后,VisualStudio为DataList自动产生ItemTemplate.用我们前面使用的template替换默认的ItemTemplate.将DataList的RepeatColumns属性
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 三十五 使用 Repeater DataList 页面 实现 主从 报表
copyright@ 2008-2022 冰点文档网站版权所有
经营许可证编号:鄂ICP备2022015515号-1