看看C#的分页,C#中用于分页的承载控件有很多,DataList、GridView、Repeater等。DataList、GridView天然支持分页,Repeater只能承载数据,没有分页功能,但利用PagedDataSource对象可让其实现分页功能。 对于分页方式,可以通过Sql每次读取指定条数的记录,或者读取出所有记录,在内存中进行分页,下面是两种分页方式的实现: View Code //分页存储过程 CREATE PROCEDURE [dbo].[PROC_PAGER] @TABLE_NAME VARCHAR(2048), --表名或视图表 @COLUMNS VARCHAR(1024), --欲选择字段列表 @WHERE VARCHAR(2000), --查询条件 @ORDER_BY VARCHAR(1000), --排序表达式 @PAGE_INDEX INT, --页号,从1开始 @PAGE_SIZE INT, --页尺寸 @RECORD_COUNT INT OUTPUT AS BEGIN IF @COLUMNS IS NULL OR LTRIM(RTRIM(@COLUMNS)) = '' BEGIN SET @COLUMNS = '*' END DECLARE @SQL_RECORD NVARCHAR(2000) SET @SQL_RECORD = 'SELECT @RECORD_COUNT = COUNT(0) FROM [' + @TABLE_NAME + '] WHERE 1 = 1 ' + @WHERE EXEC SP_EXECUTESQL @SQL_RECORD, N'@RECORD_COUNT INT OUTPUT', @RECORD_COUNT OUTPUT SET @ORDER_BY = ' ORDER BY ' + @ORDER_BY IF @PAGE_INDEX < 1 BEGIN SET @PAGE_INDEX = 1 END IF @PAGE_SIZE < 1 BEGIN SET @PAGE_SIZE = 10 END DECLARE @SQL_TEXT VARCHAR(MAX) SET @SQL_TEXT = 'SELECT ' + @COLUMNS +', ROWNUMBER FROM ( SELECT ' + @COLUMNS + ', ROW_NUMBER() OVER(' + @ORDER_BY + ') AS ROWNUMBER FROM [' + @TABLE_NAME + '] WHERE 1 = 1 ' + @WHERE + ' ) AS T WHERE ROWNUMBER BETWEEN ' + STR(((@PAGE_INDEX - 1)* @PAGE_SIZE+1)) + ' AND ' + STR(@PAGE_INDEX * @PAGE_SIZE) SET NOCOUNT _disibledevent=>///
了解原理后,可以就分页功能进行实施,思路如下: 1、Web页中定义分页数据的承载区域,用于显示分页输出。 2、建立专用ASPX页,只输出分页内容及导航。 3、建立JS分页对象,用于发起Ajax请求(请求地址为专用的分页ASPX页面),将获取到的内容加载到承载区域进行呈现。 看看具体的实现,为Repeater实现分页功能,我们自己实现一个分页的自定义控件,主要功能就是根据总页数、当前页、每页大小计算出分页导航并输出,同时将PagedDataSource与页面中的Repeater进行绑定,再利用Ajax进行无刷新分页,原理简单,计算稍微麻烦,不多做解释,自己看代码: View Code ///
"; protected static readonly string navigatePageTotalFmt = "总记录:{0} 页码:{1}/{2}
"; protected static readonly string navigateAjaxlinkFmt = "
"; private PagedDataSource pagedDataSource = null; public FMPager() { pagedDataSource = new PagedDataSource(); } public override void DataBind() { base.DataBind(); if (string.IsNullOrEmpty(repeaterId)) { return; } Control repeater = FindRepeater(Page); if (repeater == null || !(repeater is Repeater)) { return; } ChildControlsCreated = false; Repeater finalRepeater = repeater as Repeater; pagedDataSource.CurrentPageIndex = currentPageIndex; pagedDataSource.PageSize = pageSize; pagedDataSource.VirtualCount = recordCount; pagedDataSource.DataSource = DataSource; finalRepeater.DataSource = pagedDataSource; finalRepeater.DataBind(); } ///
- "); if (currentPageIndex > 1 && pageCount > 1) { sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, 1, "第一页", ""); sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, currentPageIndex - 1, "上一页", ""); } else { sbNavigate.Append(string.Format(navigateDisableLinkFmt, "第一页")); sbNavigate.Append(string.Format(navigateDisableLinkFmt, "上一页")); } //获取数字页 int navigateCount = 10; //每10页进行导航 int navigateTotal = pageCount / navigateCount; //总计能生成多少个数字导航 int pageInNavigate = ((currentPageIndex - 1) / navigateCount) + 1; //当前在第几个数字导航中 //计算数字导航开始页序及结束页序 int startIndex = (pageInNavigate - 1) * navigateCount + 1; //数字导航开始页序 int endIndex = startIndex + navigateCount - 1; //数字导航结束页序 if (endIndex > pageCount) { endIndex = pageCount; } string currentPageClass = ""; for (int i = startIndex; i <= endIndex; i++) { currentPageClass = ""; if (i == currentPageIndex) { currentPageClass = "pageactive"; } sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, i, i, currentPageClass); } //获取下一页、最后页 if (currentPageIndex != pageCount && pageCount > 1) { sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, currentPageIndex + 1, "下一页", ""); sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, pageCount, "最后页", ""); } else { sbNavigate.AppendFormat(navigateDisableLinkFmt, "下一页"); sbNavigate.AppendFormat(navigateDisableLinkFmt, "最后页"); } sbNavigate.Append("
定义一个输出控件,继承自FMPager,用于输出具体的分页的内容: View Code ///
在专用ASPX页中调用,全部内容如下,没有HTML开始结束标识,只有输出内容: View Code <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ProcPager.aspx.cs" Inherits="AjaxHandler_ProcPager" %>
名称 | 值 |
<%# Eval("NAME") %> | <%# Eval("VAL") %> |
最后是JS分页函数: View Code /* JS分页对象 参数: containerId:载体的容器ID url:分页数据地址 callbackFn:分页数据加载完成后的回调函数 */ function PagerObj(containerId, url, callbackFn){ var obj = new Object; obj.Page = page; function page(currentIndex){ var finalUrl = url; if(finalUrl.indexOf('?') == -1){ finalUrl += '?'; } finalUrl += '&p=' + currentIndex; finalUrl += '&clearBuffer=' + RandomKey(); //消除浏览器缓存 var xmlhttp = XmlHttpRequest(); if(!xmlhttp){ alert('创建xmlhttp对象异常!'); return; } xmlhttp.open('POST', finalUrl, false); xmlhttp.onreadystatechange = function(){ if(xmlhttp.readyState == 4){ document.getElementById(containerId).innerHTML = '数据加载中,请稍候...'; if(xmlhttp.status == 200){ document.getElementById(containerId).innerHTML = xmlhttp.responseText; if(callbackFn != null){ callbackFn(); } } } } xmlhttp.send(); } return obj; }
Web页面的输出: View Code <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %>
整个功能实施完毕,最后推荐使用jQuery,它封装了Ajax相关方法,我们不再需要自己实现XmlHttpRequest对象,只需利用jQuery进行异步请求即可,下面是利用jQuery实现的JS分页对象: function PagerObj(op){ var obj = new Object; obj.Page = page; var settings = $.extend({ containerId: 'divPager', //容器编号 url: '', //分页请求URL地址 extendParams: '', //URL地址扩展参数 callbackFn: null //加载完毕后的回调函数 }, op); function page(currentIndex){ var finalUrl = settings.url; if(finalUrl.indexOf('?') == -1){ finalUrl += '?'; } finalUrl += '&p=' + currentIndex; finalUrl += '&clearBuffer=' + RandomKey(); //消除浏览器缓存 $.ajax({ type: "POST", url: finalUrl, data: settings.extendParams, success: function(html){ pageCallback(html); } }); } function pageCallback(html){ $('#' + settings.containerId).html(html); if(settings.callbackFn != null){ settings.callbackFn(); } } return obj; }
调用方法: function LoadInfo(){ var url = 'AjaxHandler/ProcPager.aspx'; pagerObj = new PagerObj({ url: url, callbackFn: LoadInfoCallback }); pagerObj.Page(1); }
顺带一提,利用上面的JS分页对象可以实现同一页中的多个分页列表: View Code var pagerObj = null; var pagerTestObj = null; $(function(){ LoadInfo(); LoadTestInfo(); }) function LoadInfo(){ var url = 'AjaxHandler/ProcPager.aspx'; pagerObj = new PagerObj({ url: url }); pagerObj.Page(1); } function LoadTestInfo(){ var url = 'AjaxHandler/TestPager.aspx'; pagerTestObj = new PagerObj({ containerId: 'divTestPager', url: url }); pagerTestObj.Page(1); }
最终效果:
最新评论