您现在的位置是:网站首页> 编程资料编程资料

在ASP.NET 2.0中操作数据之三十五:使用Repeater和DataList单页面实现主/从报表_自学过程_

2023-05-24 390人已围观

简介 在ASP.NET 2.0中操作数据之三十五:使用Repeater和DataList单页面实现主/从报表_自学过程_

导言

  在前面一章里我们学习了如何用两个页分别显示主/从信息。在“主”页里我们用Repeater来显示category。每个category的name都是一个链到“从”页的hyperlink。在从页里用一个两列的DataList显示选中的category下的product。本章我们将还是使用单页,在左边显示category列表,category的名字用LinkButton显示。点击其中一个时页面postback,在右边以两列的DataList显示出相关的product。除了名字外,左边的Repeater还会显示与该category相关联的product总数。(见图1)

//img.jbzj.com/file_images/article/201605/201605100943341.png
图 1: Category的 Name 和 Product总数显示在左边

第一步: 在页面左部显示一个Repeater

  本章我们将在左边显示category,右表显示它关联的product。web页的内容可以使用标准HTML元素或者CSS来定位。到目前为止我们都是使用CSS来定位。在母板页和站点导航 一章里我们使用绝对定位来创建导航时,为导航列表和内容之间指定了明确的距离。当然CSS也可以用来对两个元素的位置进行调整。

  打开DataListRepeaterFiltering文件夹下的CategoriesAndProducts.aspx页,添加一个Repeater和DataList.ID分别设置为Categories和CategoryProducts。然后到源视图里将它们分别放到

元素里。也就是说在Repeater后面加一个闭合的
,在DataList前加一个开始的
。现在你的代码看起来应该和下面差不多:

我们需要使用float属性来将Repeater放到DataList左边,见下面代码:

Repeater
DataList

  float:left 将第一个

放到第二个的左边。width和padding-right指定了第一个
的宽和
内容和右边框的距离。更多的floating元素信息请参考Floatutorial.我们在Styles.css里创建一个新的CSS类,名为Floatleft(而不是直接在

的样式里设置):

 .FloatLeft { float: left; width: 33%; padding-right: 10px; }

  然后我们用

替换掉。
完成以上所讲的内容后,切换到设计视图。你应该看到Repeater已经在DataList左边了(由于还没有配置数据源或模板,这两个控件都是灰的)。

//img.jbzj.com/file_images/article/201605/201605100943342.png
图 2: 调整完位置后的页面

第二步: 获取每个Category关联的Products总数

  完成了样式设置后,我们现在来将category数据绑定到Repeater。如图1所示,除了category名字外,我们需要显示和它关联的product总数,为了获取这个信息我们可以:

  在ASP.NET page的code-behind 里获取这个信息. 根据给定的categoryID我们可以通过ProductsBLL类的GetProductsByCategoryID(categoryID)方法来获取关联的product总数。这个方法返回一个ProductsDataTable对象,它的Count属性表示了我们需要知道的信息。我们可以为Repeater创建一个ItemDataBound event handler,在每个category绑定到Repeater时调用这个方法然后将总数输出。

  在DataSet里更新CategoriesDataTable 添加一个NumberOfProducts列. 我们可以更新CategoriesDataTable的GetCategories()方法来包含这个信息或者保留这个方法,再创建一个新的名为GetCategoriesAndNumberOfProducts()方法。

  我们来看看这两种方法。第一种写起来更简单,因为我们不需要更新DAL。但是它需要和数据库更多的连接。在ItemDataBound event handler里调用GetProductsByCategoryID(categoryID)方法又增加了一次数据库连接(这在每个category绑定时会发生一次)。这时一共会有N+1次对数据库的请求(N为Repeater里显示的category的总数)。而第二种方法product总数从GetCategories()(或GetCategoriesAndNumberOfProducts())方法返回,这样只请求一次数据库就可以了。

在ItemDataBound Event Handler里获取Products总数

  在ItemDataBound event handler里获取product总数不需要修改DAL。只需要直接修改CategoriesAndProducts.aspx页。通过Repeater的智能标签添加一个新的名为CategoriesDataSource的ObjectDataSource。使用CategoriesBLL类的GetCategories()方法配置它。

//img.jbzj.com/file_images/article/201605/201605100943343.png
图 3: 配置 ObjectDataSource

  Repeater里的每个Category都是可点的,而且在点了之后,CategoryProducts DataList会显示那些相关的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。

  注意:在本章Repeater的view state必须开启(Repeater的声明语法里的EnableViewState="False")。在第三步我们将为ItemCommand事件创建一个event handler,在它里面我们要更新DataList的ObjectDataSource的SeleceParameters集合。如果view state 被禁用的话Repeater的ItemCommand不会被激发。想了解具体的原因和更多的信息请参考 A Stumper of an ASP.NET Question 和its solution 。

  ID为ViewCategory的LinkButton还没有设置Text属性。如果我们只需要显示category名字,我们可以通过绑定语法象下面这样来直接设置:

然而在这里我们需要显示的是category的name和proudct的总数。见下面的代码:

  我们首先要确保我们处理的是data item(ItemType为Item或AlternatingItem)然后引用刚刚绑定到当前RepeaterItem的CategoriesRow。然后调用GetCategoriesByProductID(categoryID)方法,通过Count属性获取返回的记录条数。最后将ItemTemplate里的ViewCategory LinkButton的Text属性设为"CategoryName(NumberOfProductsInCategory)"。

  注意:我们也可以在ASP.NET页的code-behind里写一个格式化功能,接收CategoryName和CategoryID的值,返回CategoryName和product总数的连接字符串。然后将结果直接赋给LinkButton的Text属性,而不需要处理itemDataBound事件。更多的格式化功能信息参考在GridView控件中使用TemplateField 和格式化DataList和Repeater的数据。添加完event handler后,在浏览器里看看页面。见图4。

//img.jbzj.com/file_images/article/201605/201605100943344.png
图 4: 显示每个 Category的 Name 和 Products总数

  更新CategoriesDataTable和CategoriesTableAdpter来包含每个Category的Product总数除了在每个category绑定到Repeater时获取product总数外,我们还可以修改DAL里CategoriesDataTable和CategoriesTableAdapter来包含这个信息.我们在CategoriesDataTable里加一列.打开App_Code/DAL/Northwind.xsd,右键点DataTable,选择Add/Column.见图5.

//img.jbzj.com/file_images/article/201605/201605100943345.png
图 5: 为CategoriesaDataSource增加一个新列

  这样会添加一个名为Column1的列,你可以很方便的修改它的名字.将它重命名为NumberOfProducts.然后我们需要配置这列的属性.点这个列,来到属性窗口.将DataType从System.String修改为System.Int32.将ReadOnly属性设为True.见图6.

//img.jbzj.com/file_images/article/201605/201605100943346.png
图 6: 设置新列的属性

  现在CategoriesDataTable里已经包含了NumberOfProducts列,但它的值还没有设置.我们可以修改GetCategories()方法,当每次获取category信息的时候返回它的信息.在这里由于只是本章用到了这个数据,我们来创建一个新的名为GetCategoriesAndNumberOfProducts().右键点CategoriesTableAdapter,选择New Query.会出现TableAdapter Query配置向导.选择SQL statement.

//img.jbzj.com/file_images/article/201605/201605100943347.png
图 7: 选择SQL Statement

//img.jbzj.com/file_images/article/201605/201605100943348.png
图 8: SQL Statement 返回行数

下一步需要我们写sql语句.下面的语句返回每个category的CategoryID,CategoryName,Description和相关product的总数:

//img.jbzj.com/file_images/article/201605/201605100943349.png
图 9: 使用的sql语句

  注意计算product总数的子查询的别名为NumberOfProducts.它和CategoriesDataTable的NumberOfProducts列关联.最后一步是写方法的名字.分别为Fill a DataTable和Return a DataTable命名为FillWithNumberOfProducts和GetCategoriesAndNumberOfProducts.

//img.jbzj.com/file_images/article/201605/2016051009433410.png
图 10: 为新的TableAdapter的方法命名

  现在DAL已经修改完了.由于我们所有展现层,BLL,DAL是逐层调用,所以我们需要在CategoriesBLL类的添加相应的GetCategoriesAndNumberOfProducts方法.

  完成DAL和BLL后,我们来将数据绑定到Categories Repeater.如果在"在ItemDataBound Event Handler里获取Products总数"那部分里你已经为Repeater创建了ObjectDataSource,删掉它,然后去掉Repeater的DataSourceID属性,同样去掉ItemDataBound事件.Repeater现在回到了初始状态,添加一个名为CategoriesDataSource的ObjectDataSource.使用CategoriesBLL类的GetCategoriesAndNumberOfProducts()方法来配置它.见图11.

//img.jbzj.com/file_images/article/201605/2016051009433411.png
图 11: 配置ObjectDataSource<

-六神源码网