在ASP.NET 2.0中操作数据之四十二:DataList和Repeater数据排序(一)

导言

  DataList和Repeater数据分页里我们学习了如何在DataList里添加分页功能。我们在ProductsBLL类里创建了一个名为GetProductsAsPagedDataSource的方法,它返回一个PagedDataSource对象。当绑定到DataList或Repeater时,他们将只显示请求页的数据。这个技术和GridView,DetailsView,FormView的内置分页功能原理差不多。

  除了分页外,GridView还提供了内置的排序功能,而DataList和Repeater都没有。然而排序功能可以通过一点点代码就实现。本章我们将学习如何在DataList和Repeater里实现排序功能,我们还将创建一个同时支持分页和排序的DataList或Repeater。

回顾一下排序

  如我们在分页和排序报表数据里看到的,GridView提供了排序的支持。每个GridView的字段可以有一个关联的SortExpression,它指明了对数据进行排序依据的字段。当GridView的AllowSorting属性设为true时,每个包含SortExpression 属性的GridView的字段的header都表现为一个LinkButton。当点一个header时,页面postback,数据会根据被点字段的SortExpression进行排序。另外,SortDirection属性指明了数据是升序或降序。

  当将GridView绑定到数据源控件时,它会将SortExpression和SortDirection传给数据源控件。数据源控件获取数据并根据SortExpression和SortDirection进行排序。然后将数据返回给GridView。

在DataList或Repeater里实现这个功能,我们需要: 

  创建一个排序界面
  将排序的字段和方向(升序或降序)记下
  指导ObjectDataSource根据特定字段排序

  我们将在第三和四步来处理上面三个步骤。然后我们将看看如何让DataList或Repeater同时支持这两个功能(分页和排序)。

第二步: 在 Repeater里显示 Products

  在实现排序功能前,首先创建一个列出所有product的Repeater。打开PagingSortingDataListRepeater文件夹里的Sorting.aspx页。添加一个Repeater,将ID设为SortableProducts。从智能标签里创建一个名为ProductsDataSource的ObjectDataSource。用ProductsBLL类的GetProducts()方法配置它。在INSERT, UPDATE, DELETE标签的下拉列表里选择“(None)”。


图 1: 创建 ObjectDataSource


图 2: 在 UPDATE, INSERT, DELETE 标签的下拉列表里选择 “(None)”

  在绑定到数据源后,Visual Studio没有自动为Repeater创建ItemTemplate,这点和DataList不一样。而且由于Repeater控件的智能标签里没有象DataList里那样的“Edit Templates”选项,因此我们需要直接添加声明代码。我们使用和前一章一样的ItemTemplate,它显示product的 name, supplier, category。

  现在你的Repeater和ObjectDataSource的声明标记看起来应该和下面差不多:

<asp:Repeater ID="SortableProducts" DataSourceID="ProductsDataSource"

 EnableViewState="False" runat="server">

 <ItemTemplate>

  <h4><asp:Label ID="ProductNameLabel" runat="server"

   Text='<%# Eval("ProductName") %>'></asp:Label></h4>

  Category:

  <asp:Label ID="CategoryNameLabel" runat="server"

   Text='<%# Eval("CategoryName") %>'></asp:Label><br />

  Supplier:

  <asp:Label ID="SupplierNameLabel" runat="server"

   Text='<%# Eval("SupplierName") %>'></asp:Label><br />

  <br />

  <br />

 </ItemTemplate>  

</asp:Repeater>

<asp:ObjectDataSource ID="ProductsDataSource" runat="server"

 OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"

 SelectMethod="GetProducts">

</asp:ObjectDataSource>

图 3 是现在浏览该页的样子。


图 3: 显示 Product的 Name, Supplier, Category

第三步: 指导 ObjectDataSource 对数据进行排序

  为了让Repeater里显示的数据排序,我们需要将数据排序的sort expression告诉ObjectDataSource。在ObjectDataSource获取数据前,首先激发的是Selecting event,它给我们提供了一个指定sort expression的机会。Selecting event handler 有一个ObjectDataSourceSelectingEventArgs 类型的参数,它有一个名为Arguments的 DataSourceSelectArguments类型的属性.。DataSourceSelectArguments类被设计用来将数据相关的请求从数据的消费者传给数据源控件,它有一个SortExpression property。

  创建一个Selecting event handler,用以下代码将排序的信息从ASP.NET页传给ObjectDataSource:

protected void ProductsDataSource_Selecting

 (object sender, ObjectDataSourceSelectingEventArgs e)

{

 e.Arguments.SortExpression = sortExpression;

}

  sortExpression 需要赋值为排序字段的名字(例如“ProductName”)。它没有排序方向相关的属性,因此如果需要以降序来排序,将“DESC”附加在sortExpression 的值后面(比如“ProductName DESC”)。

  继续试一下硬编码将sortExpression 赋为不同的值,并浏览页面 。如图4,当使用“ProductName DESC”作为sortExpression时,product会根据name的字母顺序反向排序。


图 4: Product 根据Name 的字母顺序反向排序

第四步: 创建排序界面并记下Sort Expression 和 Direction

  开启GridView的排序支持会将每个可排序的字段的header text转换为一个LinkButton,当被点击时,会进行相对应的排序。这样的排序对GridView来说是很合理的,因为它的数据是以列的形式整齐的展示。而对DataList和Repeater来说,需要不同的排序界面。一个常见的数据列表(相对于数据网格)的排序界面是使用一个提供排序字段的下拉列表。我们本章将完成这样的界面。

  在SortableProducts Repeater上方添加一个DropDownList,将ID设为SortBy。在属性窗口里点Items属性打开ListItem集合编辑器。添加ListItems,让数据根据ProductName, CategoryName, SupplierName 字段排序。同时添加ListItem让product根据反向的name的顺序排序。

  ListItem的Text属性可以设为任何值(比如“Name”),但是Value必须设为数据字段的名字(比如“ProductName”)。添加字符串“DESC”到数据字段名字后面,来让结果以降序排序,比如“ProductName DESC”。


图 5:为每个可排序的字段添加 ListItem

  最后在DropDownList的右边添加一个Button。将ID设为RefreshRepeater,Text设为“Refresh”。

  完成这些后,DropDownList和Button的声明语法看起来应该和下面差不多:

<asp:DropDownList ID="SortBy" runat="server">

 <asp:ListItem Value="ProductName">Name</asp:ListItem>

 <asp:ListItem Value="ProductName DESC">Name (Reverse Order)

  </asp:ListItem>

 <asp:ListItem Value="CategoryName">Category</asp:ListItem>

 <asp:ListItem Value="SupplierName">Supplier</asp:ListItem>

</asp:DropDownList>

<asp:Button runat="server" ID="RefreshRepeater" Text="Refresh" />

完成DropDownList后,我们需要更新ObjectDataSource的Selecting event handler,来让它使用选择的SortBy ListItem的Value作为sort expression,代替前面的硬编码。

protected void ProductsDataSource_Selecting

 (object sender, ObjectDataSourceSelectingEventArgs e)

{

 // Have the ObjectDataSource sort the results by the selected

 // sort expression

 e.Arguments.SortExpression = SortBy.SelectedValue;

}

  现在第一次浏览页的时候,由于默认的SortBy ListItem 的值为ProductName,因此product会根据ProductName字段来排序。见图6。选择一个其它的项–比如“Category”–然后点Refresh,这时会postback,数据会根据category name来重新排序,见图7。


图 6: 第一次 Products 根据 Name 排序


图 7: 现在 Products 根据 Category 来排序

  注意:点Refresh button会让数据重新排序是因为Repeater的view state被禁用了,因此Repeater在每次postback时重新绑定到数据源。如果你开启Repeater的view state,这时改变drop-down list不会对排序有任何影响。为了修复这个问题,你可以为Refresh Button的 Click event创建一个event handler,来重新绑定Repeater到数据源(调用Repeater的DataBind()方法)。

  记下Sort Expression 和 Direction(排序表达式和排序方向)

  如果包含可排序的DataList或Repeater的页可能有其它和排序无关的postback发生,那么我们需要在postback过程中记下sort expression 和 direction。比如,我们将本章的Repeater修改成为每个product包含一个Delete button。当用户点Delete button时我们会执行一些代码来删除选择的product,然后将数据绑定到Repeater。如果排序的信息在postback过程中没有被保存下来,那么显示的数据会回复到最初的排序状态。

  本章里,DropDownList隐式的为我们将sort expression 和 direction保存在它的view state里。如果我们使用不同的排序界面–LinkButton提供不同的排序选项–我们就需要在postback过程中记下排序的信息。这个可以通过将排序的参数记在page的view state里,或者记在querystring里,或者通过一些其它状态保存机制来实现。

  祝编程快乐!

作者简介

  本系列教程作者 Scott Mitchell,著有六本ASP/ASP.NET方面的书,是4GuysFromRolla.com的创始人,自1998年以来一直应用 微软Web技术。大家可以点击查看全部教程《[翻译]Scott Mitchell 的ASP.NET 2.0数据教程》,希望对大家的学习ASP.NET有所帮助。

时间: 2016-05-12

在ASP.NET 2.0中操作数据之四十七:用SqlDataSource控件插入、更新、删除数据

导言: 正如在教程概述插入.更新和删除数据里讨论的那样,GridView控件内置更新和删除功能,而DetailsView和FormView控件不仅具有编辑和删除功能,还有插入功能.我们不要写一行代码就可一将这些功能直接应用于一个数据源控件.在这篇教程里,我们指出ObjectDataSource控件最好与GridView, DetailsView和FormView控件一起使用,才更好的实现插入.更新和删除功能.对SqlDataSource控件来说,同样如此! 对ObjectDataSource控件

在ASP.NET 2.0中操作数据之四十一:DataList和Repeater数据分页

导言 分页和排序是显示数据时经常用到的功能.比如,在一个在线书店里搜索关于ASP.NET 的书的时候,可能结果会是成百上千,而每页只列出十条.而且结果可以根据title(书名),price(价格),page count(页数),author name(作者)等来排序.我们在分页和排序报表数据 里已经讨论过, GridView, DetailsView, 和FormView 都有内置的分页功能,仅仅只需要勾一个checkbox就可以开启.GridView 还支持内置的排序. 不幸的是,DataLi

在ASP.NET 2.0中操作数据之四十五:DataList和Repeater里的自定义Button

导言 在前面关于DataList 和Repeater 的7章教程里,我们分别创建了只读和可以编辑删除的例子.为了让DataList有编辑和删除的功能,我们在ItemTemplate里添加了一些button,当点击时,引起postback,并根据button的CommandName属性激发相关的事件.例如,添加一个CommandName为"Edit"的button,在postback时会激发EditCommand事件,如果CommandName为"Delete"则激发

SqlDataSource 链接Access 数据

还的我耗费了好长时间,研究如何用AccessDataSource链接有密码的access数据库,也没有成功. <appSettings/> <connectionStrings> <add name="ConnectionString" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\good.mdb;Persist Security I

在ASP.NET 2.0中操作数据之四十三:DataList和Repeater数据排序(二)

接着上篇介绍,上篇已经通过DropDownList简单实现了排序的功能,下面让我们看看带有分页的排序该怎么做. 第五步: 为使用默认分页的DataList添加排序的支持 打开PagingSortingDataListRepeater文件夹里的SortingWithDefaultPaging.aspx和Paging.aspx 页.在Paging.aspx 页里查看源文件.将图8里选择的文本复制下来,然后粘贴到SortingWithDefaultPaging.aspx 页里的<asp:Content

ASP.NET2.0数据库入门之SqlDataSource

当使用SqlDataSource控件选择数据时,可以从两个属性:ConnectionString和SelectCommand开始,如下所示: <asp:SqlDataSource ID="MySourceControlName" Runat="server" ConnectionString="Server=MyServer ; Database=Northwind" SelectCommand=" SELECT Fieldl,

在ASP.NET 2.0中操作数据之四十:自定义DataList编辑界面

导言 DataList的编辑界面由EditItemTemplate里的标记语言和web控件定义.在目前为止所做的DataList编辑功能的例子里,编辑界面都只包含TextBox.在前面一章里,我们通过添加验证控件来增加了用户体验,提高了可用性. EditItemTemplate可以包含除了TextBox以外的很多控件,比如DropDownList, RadioButtonList, Calendar等.和使用TextBox一样,使用这些控件自定义编辑界面时,步骤如下: 为EditItemTemp

在ASP.NET 2.0中操作数据之三十九:在DataList的编辑界面里添加验证控件

导言 到目前为止的讨论编辑DataList的教程里,没有包含任何验证用户的输入,即使是用户非法输入- 遗漏了product的name或者负的price- 会导致异常.在前面一章里我们学习了如何在DataList的UpdateCommand事件处理中添加异常处理代码,以便在出现异常时捕捉它并显示友好的错误信息.然而理想的编辑界面应该包含验证控件,用来在第一时间里阻止用户输入一些非法数据. 本章我们将学习在DataList的EditItemTemplate里添加验证控件从而提供一个更安全的编辑界面,

在ASP.NET 2.0中操作数据之四十六:使用SqlDataSource控件检索数据

导言 到目前为止,我们探讨的教程是由表现层,业务逻辑层和数据访问层构成的层次体系结构.数据访问层和业务逻辑层分别在教程第一和第二章提到.在Displaying Data With the ObjectDataSource 这篇教程里,我们探讨了怎样用ASP.NET 2.0的新控件--ObjectDataSource控件在表现层展示数据. 本教程到目前为止用这种层次结构来处理数据.然而绕过这种体系结构,通过直接把数据查询和业务逻辑放在Web页面上,也可以达到直接在ASP.NET页面上访问,插入,更

在ASP.NET 2.0中操作数据之四十四:DataList和Repeater数据排序(三)

第七步: 在自定义分页的Repeater 里添加排序功能 现在已经完成了自定义分页,我们再来添加排序功能.ProductsBLL类的GetProductsPagedAndSorted方法和GetProductsPaged一样有startRowIndex 和 maximumRows 参数,不一样的是它还多了一个sortExpression 参数.在SortingWithCustomPaging.aspx里使用GetProductsPagedAndSorted方法我们需要: 将ObjectDataS

aspx中的mysql操作类sqldatasource使用示例分享

复制代码 代码如下: <%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtmlll/DTD/xhtmlll.dtd"> <script runat="server"> </script> <html xmlns="h

PHP实现的mysql操作类【MySQL与MySQLi方式】

本文实例讲述了PHP实现的mysql操作类.分享给大家供大家参考,具体如下: 首先是mysql方式 <?php class ConnectionMySQL{ //主机 private $host="localhost"; //数据库的username private $name="root"; //数据库的password private $pass=""; //数据库名称 private $table="phptest"

浅谈PHP值mysql操作类

浅谈PHP值mysql操作类 <?php /** * Created by PhpStorm. * User: Administrator * Date: 2016/6/27 * Time: 18:55 */ Class Mysqls{ private $table; //表 private $opt; public function __construct($host,$user,$pwd,$name,$table_names) { $this->db=new mysqli($host,$u

.Net中的json操作类用法分析

本文实例展示了.Net中的json操作类用法,对于进行.Net程序设计来说是非常重要的技巧.具体分析如下: 首先需要引用 System.Web.Extensions.dll 这个类库 命名空间需要加上:System.Web.Script.Serialization   数据结构如下: public class Team { public string Name { get; set; } public List<User> Users { get; set; } } public class

python写日志文件操作类与应用示例

本文实例讲述了python写日志文件操作类与应用.分享给大家供大家参考,具体如下: 项目的开发过程中,日志文件是少不了的,通过写日志文件,可以知道程序运行的情况.特别当部署在生产环境中的时候,这个时候一般不能debug , 当然在有些情况时可以 remote debug (远程debug).那种情况另当别论.还是用通常的写日志的方法,比如在 java 中,经常可以看到 log4j,sf4j,logback等三方组件来写日志. 在python中如何实现呢,其实python 本身也带了日志操作的库.

PHP全功能无变形图片裁剪操作类与用法示例

本文实例讲述了PHP全功能无变形图片裁剪操作类与用法.分享给大家供大家参考,具体如下: 如果需要图片裁剪,或生成缩略图,这个基本上没有问题,全部需要的功能都在里面,全部都是无变形的. 这里我们划分为四种模式: 1. 任意图片裁剪到指定大小,超过的,剧中裁剪,并且最大化缩放,不够的拉伸, 2. 超过的剧中裁剪,而不足的,不拉伸,即只缩小,不放大裁剪,会产生补白,可以用png透明度来消除 3. 保留全部图片信息.不裁剪,只缩放,不足的补白. 4. 保留全部图片信息.不裁剪,只缩放,不足的不补白,产生

Java日期操作类常见用法示例

本文实例讲述了Java日期操作类常见用法.分享给大家供大家参考,具体如下: 一 取出当前日期时间 1 代码 import java.time.*; public class GetDatetime { public static void main(String[] args) { // 创建时间对象,获取当前时间 LocalDateTime timePoint = LocalDateTime.now( ); // 当前时间 System.out.println("--当前时间----"

Java编程中静态内部类与同步类的写法示例

java静态内部类 将某个内部类定义为静态类,跟将其他类定义为静态类的方法基本相同,引用规则也基本一致.不过其细节方面仍然有很大的不同.具体来说,主要有如下几个地方要引起各位程序开发人员的注意.     (一)一般情况下,如果一个内部类不是被定义成静态内部类,那么在定义成员变量或者成员方法的时候,是不能够被定义成静态成员变量与静态成员方法的.也就是说,在非静态内部类中不可以声明静态成员.     (二)一般非静态外部类可以随意访问其外部类的成员变量以及方法(包括声明为private的方法),但是

Java中File文件操作类的基础用法

前言 众所周知Java提供File类,让我们对文件进行操作,下面就来简单整理了一下File类的用法. 话不多说了,来一起看看详细的介绍吧 1.基本概念 File:文件和目录路径名的抽象表示形式,代表文件或者文件夹. 2.构造方法 // 根据parent抽象路径名和child路径名字符串创建一个新File实例 File(File parent, String child) // 通过将给定路径名字符串转换为抽象路径名来创建一个新File实例 File(String pathname) // 根据p

PHP封装mysqli基于面向对象的mysql数据库操作类与用法示例

本文实例讲述了PHP封装mysqli基于面向对象的mysql数据库操作与用法.分享给大家供大家参考,具体如下: 首先封装好mysql类 mysql.php <?php class Mysql{ private static $host="localhost"; private static $user="root"; private static $password="123456"; private static $dbName=&quo