园子里分页代码是老生常谈了,可惜找到的不是有问题就是满足不了自己的需求,静下心来重新改写了在用的一个分页器,因为有测试会比较稳定,虽然测试覆盖可能还不是很全面。
用例代码:
new CNBlogs.Presentation.Web.PagingBuilder() { FirstPageLink = firstLink, OnlickJsFunc = "Return true;", PageIndex = (int)(p??1), ShowPageCount = 11, TotalCount = 1, UrlFormat = urlFormate, PageSize = PAGE_SIZE, AjaxUrl = "/" };//MVC View Code@{ Html.RenderPaging(Model.Paging);}
先上代码:
public class PagingBuilder { private TextWriter _writer; private int _totalCount; private int _pageIndex; private int _pageSize; private int _showPageCount; private string _urlFormat; private string _onclickJsFunc; private string _firstPageLink; private string _ajaxUrl = "/ToolkitPaging/load"; private int _totalPageCount; private int _lastPage = 1; #region Properties public bool OnlyLinkText { get; set; } ////// 总记录数 /// public int TotalCount { get { return _totalCount; } set { _totalCount = value; } } ////// 当前页码 /// public int PageIndex { get { return _pageIndex; } set { _pageIndex = value; } } ////// 每页显示的记录数 /// public int PageSize { get { return _pageSize; } set { _pageSize = value; } } ////// 默认显示的页码数 /// public int ShowPageCount { get { return _showPageCount; } set { _showPageCount = value; } } ////// 页码链接地址 /// public string UrlFormat { get { return _urlFormat; } set { _urlFormat = value; } } ////// 页码链接onclick事件处理js方法,pageIndex,pageSize参数无需添加 /// public string OnlickJsFunc { get { return _onclickJsFunc; } set { _onclickJsFunc = value; } } ////// 第1页链接地址 /// public string FirstPageLink { get { return _firstPageLink; } set { _firstPageLink = value; } } ////// ajax加载分页的请求地址,默认是/paging/load /// public string AjaxUrl { get { return _ajaxUrl; } set { _ajaxUrl = value; } } ////// ajax加载分页的js回调方法,有默认实现 /// private string _ajaxCallbak; public string AjaxCallbak { get { return _ajaxCallbak; } set { _ajaxCallbak = value; } } ////// 顶部分页Html标签Id /// private string _topPagerId = "pager_top"; public string TopPagerId { get { return _topPagerId; } set { _topPagerId = value; } } public bool IsRenderScript { get; set; } #endregion public PagingBuilder() { IsRenderScript = true; } public void Render(TextWriter writer) { _writer = writer; Render(); } public void Render() { if (_totalCount <= _pageSize) { return; } if (this.IsRenderScript) { _writer.Write(""); } if (!this.OnlyLinkText) { _writer.Write(""); RenderScript(); } } private void Head() { int totalPageCount = _totalPageCount; int currint = _showPageCount / 2; if (_pageIndex > 1) { //处理上一页的连接 RenderPage(_pageIndex - 1, this.OnlyLinkText ? "Prev " : "< Prev"); } for (int i = 1; i <= (_showPageCount > totalPageCount ? totalPageCount : _showPageCount); i++) { RenderPage(i); } if (_lastPage + 1 < totalPageCount) { _writer.Write("..."); } if (_lastPage < totalPageCount) { RenderPage(totalPageCount); } if (_pageIndex < totalPageCount) { //处理下一页的链接 RenderPage(_pageIndex + 1, this.OnlyLinkText ? "Next" : "Next >"); } } private void Middle() { int totalPageCount = _totalPageCount; int currint = _showPageCount / 2; if (_pageIndex > 1) { //处理上一页的连接 RenderPage(_pageIndex - 1, this.OnlyLinkText ? "Prev " : "< Prev"); } if (_pageIndex - currint > 1) { //处理首页连接 RenderPage(1); if(_pageIndex-currint>2) {_writer.Write("...");} } for (int i = 0; i <= _showPageCount; i++) { var c = _pageIndex + i - currint; //一共最多显示10个页码,前面5个,后面5个 if (c > 1 && c < totalPageCount) { if (c != 2 && _lastPage == 1) { _writer.Write("..."); } RenderPage(c); } } if (_pageIndex + currint < totalPageCount) { if (_lastPage + 1 != totalPageCount) { _writer.Write("..."); } RenderPage(totalPageCount); } if (_pageIndex < totalPageCount) { //处理下一页的链接 RenderPage(_pageIndex + 1, this.OnlyLinkText ? "Next" : "Next >"); } } private void Tail() { int totalPageCount = _totalPageCount; int currint = _showPageCount / 2; if (_pageIndex > 1) { //处理上一页的连接 RenderPage(_pageIndex - 1, this.OnlyLinkText ? "Prev " : "< Prev"); } if (_pageIndex - currint > 1&&_totalPageCount>_showPageCount) { //处理首页连接 RenderPage(1); } for (int i = ((_totalPageCount - _showPageCount) < 0 ? 0 : (_totalPageCount - _showPageCount)) + 1; i <= _totalPageCount; i++) { if (i > 2 && _lastPage == 1) { _writer.Write("..."); } RenderPage(i); } if (_pageIndex < totalPageCount) { //处理下一页的链接 RenderPage(_pageIndex + 1, this.OnlyLinkText ? "Next" : "Next >"); } } private void RenderPage(int pageIndex) { RenderPage(pageIndex, string.Empty); } private void RenderPage(int pageIndex, string pageText, bool visible = true) { _lastPage = pageIndex; if (OnlyLinkText) { if (pageIndex == _pageIndex) { _writer.Write("-"); } _writer.Write(" "); if (!string.IsNullOrEmpty(pageText)) { _writer.Write(pageText); } else { _writer.Write(pageIndex); } if (pageIndex == _pageIndex) { _writer.Write("-"); } return; } string link = ""; if (string.IsNullOrEmpty(_urlFormat)) { link = "javascript:void(0)"; } else { if (pageIndex == 1 && !string.IsNullOrEmpty(_firstPageLink)) { link = _firstPageLink; } else { link = string.Format(_urlFormat, pageIndex); } } _writer.Write(" "); } private void RenderScript() { _writer.Write(""); } }"); } //总页数 _totalPageCount = (_totalCount + _pageSize - 1) / _pageSize; int currint = _showPageCount / 2; if (_pageIndex - currint <= 1) { Head(); } else if (_pageIndex + currint >= _totalPageCount) { Tail(); } else { Middle(); } if (!this.OnlyLinkText) { _writer.Write(""); } if (IsRenderScript) { _writer.Write("
测试分页效果,这里设定的弹性显示页数为11:
Render_Test : Passed
1//1 Result: 1//2 Result:- 1- 2 Next 2//2 Result: Prev 1- 2- 1//3 Result:- 1- 2 3 Next 2//3 Result: Prev 1- 2- 3 Next 3//3 Result: Prev 1 2- 3- 1//9 Result:- 1- 2 3 4 5 6 7 8 9 Next 3//9 Result: Prev 1 2- 3- 4 5 6 7 8 9 Next 5//9 Result: Prev 1 2 3 4- 5- 6 7 8 9 Next 7//9 Result: Prev 1 2 3 4 5 6- 7- 8 9 Next 9//9 Result: Prev 1 2 3 4 5 6 7 8- 9- 1//11 Result:- 1- 2 3 4 5 6 7 8 9 10 11 Next 3//11 Result: Prev 1 2- 3- 4 5 6 7 8 9 10 11 Next 5//11 Result: Prev 1 2 3 4- 5- 6 7 8 9 10 11 Next 7//11 Result: Prev 1 2 3 4 5 6- 7- 8 9 10 11 Next 10//11 Result: Prev 1 2 3 4 5 6 7 8 9- 10- 11 Next 1//13 Result:- 1- 2 3 4 5 6 7 8 9 10 11... 13 Next 3//13 Result: Prev 1 2- 3- 4 5 6 7 8 9 10 11... 13 Next 5//13 Result: Prev 1 2 3 4- 5- 6 7 8 9 10 11... 13 Next 7//13 Result: Prev 1 2 3 4 5 6- 7- 8 9 10 11 12 13 Next 8//13 Result: Prev 1... 3 4 5 6 7- 8- 9 10 11 12 13 Next 9//13 Result: Prev 1... 3 4 5 6 7 8- 9- 10 11 12 13 Next 10//13 Result: Prev 1... 3 4 5 6 7 8 9- 10- 11 12 13 Next 11//13 Result: Prev 1... 3 4 5 6 7 8 9 10- 11- 12 13 Next 12//13 Result: Prev 1... 3 4 5 6 7 8 9 10 11- 12- 13 Next 1//200 Result:- 1- 2 3 4 5 6 7 8 9 10 11... 200 Next 3//200 Result: Prev 1 2- 3- 4 5 6 7 8 9 10 11... 200 Next 5//200 Result: Prev 1 2 3 4- 5- 6 7 8 9 10 11... 200 Next 7//200 Result: Prev 1 2 3 4 5 6- 7- 8 9 10 11 12 13... 200 Next 8//200 Result: Prev 1...... 3 4 5 6 7- 8- 9 10 11 12 13 14... 200 Next 9//200 Result: Prev 1...... 4 5 6 7 8- 9- 10 11 12 13 14 15... 200 Next 10//200 Result: Prev 1...... 5 6 7 8 9- 10- 11 12 13 14 15 16... 200 Next 11//200 Result: Prev 1...... 6 7 8 9 10- 11- 12 13 14 15 16 17... 200 Next 12//200 Result: Prev 1...... 7 8 9 10 11- 12- 13 14 15 16 17 18... 200 Next 88//200 Result: Prev 1...... 83 84 85 86 87- 88- 89 90 91 92 93 94... 200 Next 199//200 Result: Prev 1... 190 191 192 193 194 195 196 197 198- 199- 200 Next