数据分页 文章来自http://blog.joycode.com/microhelper/articles/1265.aspx
属性
AllowSorting: 是否允许分页
PageSize: 页的大小
CurrentPageIndex: 当前页,CurrentPageIndex应该大于等于0并且小于等于PageCount
PageCount :页数
VirtualItemCount: DataGrid需要根据Record的数目来计算页数,但是Custom Paging模式不需要一次得到所有的Record,所以需要显式为VirtualItemCount赋值
事件
PageIndexChanged: 改变PageIndex时触发。在PageIndexChanged中更新CurrentPageIndex属性并且重新绑定DataSource(一定要重新绑定,如果不重新绑定DataSource的话DataGrid会用ViewState的信息)
定制
用DataGridPagerStyle类或者
包括BackColor;Font;ForeColor;HorizontalAlign;Mode;NextPageText;PrevPageText;PageButtonCount;Position;Width
如果要自定义导航栏,比如1,2 -->[1],[2]可以在OnItemCreated事件里面实现,DataGrid的页导航栏是TableRow对象,包含一个跨越所有列的TableCell对象,要访问分页按钮,需要遍历TableRow的Controls集合,(分页按钮之间的空格也是控件,遍历时可以跳过)
如果要实现更复杂的导航栏,可以把DataGrid自带的导航栏的Visible属性设置为False,然后加入自己的导航栏,自定义的导航栏是与DataGrid可以是相互独立的。
更复杂的定制可以在OnItemCreated事件里面实现。
Default Paging模式
设置AllowSorting为True,只显示PageSize大小的reocrd
如果DataGrid分页模式用Default Paging, 那么DataSource需要是一个实现ICollection接口的对象,因为DataGrid需要知道DataSouce对象有多少Record(DataSet实现了ICollection接口但是DataReader没有)。
Default Paging模式下,会接受所有的Data,但是只显示其中一部分。
Custom Paging模式
如果DataGrid分页模式用Custom Paging,DataSource不需要实现ICollection,所以可以用DataReader。
获得VirtualItemCount可以用ExecuteScalar,ExecuteScalar执行查询,只返回查询所返回的结果集中第一行的第一列。
要计算某一个Reocrd是DataSource中的第几个reccord,可以在存储过程中借助一个含有递增field(比如:IncreasingID int IDENTITY(1,1))的临时表,但是此法不适用于数据量非常大的情况
对于以递增的整数为主键的table,可以把每页的最小主键的最大主键保存下来,然后结合select top和order by来实现分页(注意order by的顺序,要根据查看前一页还是查看后一页决定用DESC还是用ASC),不过这种方法不适用Mode="NumericPages"
或者用set rowcount xxxx来代替select top,不过不要忘了最后调用set rowcount 0
或者将DataSource的PrimaryKey排序后存入ArrayList中,然后根据PageSize,CurrentPageIndex,NewPageIndex等计算出此页的PrimaryKey范围,用Join和GetRange将该范围内的PrimaryKey组成一个字符串,传入存储过程select ... from ... where ... And PrimaryKeyColumn IN (...)。因为有Index的协助,对PrimaryKey的操作应该非常快。
或者用嵌套的select top语句,比如每页n条记录,要查看第m页, 可以
select top * from (
select top n * from
(select top n*m * from table_name order by primarykey)
order by primarykey desc
)order by primarykey
说实话,这方法很笨
还有一种比较快的方法是利用Database的游标,例子如下
declare @pagesize int
declare @page int
declare @total int
declare @start int
declare @end int
declare @maxid int
declare @minid int
set @pagesize = 10
set @page = 0 --Page从0开始
select @start = @page * @pagesize + 1
select @end = @start+ @pagesize - 1
declare pagecursor cursor SCROLL for
select contact_id from table_contact order by contact_id
open pagecursor
set @total = @@CURSOR_ROWS
fetch absolute @start from pagecursor into @minid
if @end > @total
fetch last from pagecursor into @maxid
else
fetch absolute @end from pagecursor into @maxid
close pagecursor
deallocate pagecursor
select contact_id, contact_firstname, contact_lastname
from table_contact
where contact_id between @minid and @maxid
order by contact_id
对不支持分页的控件可以借助于PagedDataSource类。