之前写的,很凌乱,而且,几乎不粘代码,这不便于理解和也无法直接寻找可用代码。以后的文章会尽量引入代码实例。
这次需要一个翻页控件。之前webform直接拖个aspnetpager,写写前台样式和后台代码就好了,需要数据绑定时可以直接用pager控件的属 性,或者可以直接在sqldatasource或者entitydatasource里绑定parameter为controlparameter,指向 相应控件的属性。(代码就不找了)
现在MVC框架下,服务端控件被取消了,似乎分页变得复杂了不少。寻找微软提供的解决方案,没有找到。(可能是我找的不够细致)在网上看到说自己写个HtmlHelper的扩展,小研究了一下,发现不是很符合我的胃口。哈哈,那就自己整吧。
先看下扩展:
必须由要扩展的类型同一命名空间的下的类承载,一般定义为static class,命名为扩展功能+Extensions。对于类中的方法,应当使用static方法。方法的第一个参数为要扩展的类型,并使用this修饰 符。 还有就是,扩展方法作为静态方法,无法访问被扩展对象的非静态方法和属性。
好了,开工。扩展参考了网上某位同仁的代码,但是代码基本上重写了,保留了思想,哈哈。忘记地址了,这里就不贴了。
- using System.Reflection;
- using System.Text;
- using System.Web.Routing;
- namespace System.Web.Mvc
- {
- #region 分页配置类
- /// <summary>
- /// 分页元素位置
- /// </summary>
- public enum PagerElementPosition
- {
- Left,
- Right
- }
- /// <summary>
- /// 配合Pager扩展,分页控件设置类
- /// </summary>
- public class PagerConfig
- {
- /// <summary>
- /// 记录总条数
- /// </summary>
- public int TotalRecord { get; set; }
- /// <summary>
- /// 记录的单位,默认为“条”
- /// </summary>
- public string RecordUnit { get; set; }
- /// <summary>
- /// 记录的名称,默认为“记录”
- /// </summary>
- public string RecordName { get; set; }
- /// <summary>
- /// 当前页码的参数名
- /// </summary>
- public string CurrentPageKey { get; set; }
- /// <summary>
- /// 当前页码 只读
- /// </summary>
- public int CurrentPage
- {
- get
- {
- if (HttpContext.Current.Request.Params[CurrentPageKey] == null)
- {
- return 1;
- }
- else
- {
- try
- {
- int currentPage = Convert.ToInt32(HttpContext.Current.Request.Params[CurrentPageKey]);
- if (currentPage < 1)
- {
- return 1;
- }
- else if (currentPage > TotalPage)
- {
- return TotalPage;
- }
- else
- {
- return currentPage;
- }
- }
- catch
- {
- return 1;
- }
- }
- }
- }
- private int _PageSize;
- /// <summary>
- /// 每页显示记录数
- /// </summary>
- public int PageSize
- {
- get
- {
- return _PageSize;
- }
- set
- {
- if (value < 1)
- {
- _PageSize = 1;
- }
- else
- {
- _PageSize = value;
- }
- }
- }
- /// <summary>
- /// 总页数 只读
- /// </summary>
- public int TotalPage
- {
- get
- {
- return (int)Math.Ceiling(TotalRecord / (double)PageSize);
- }
- }
- /// <summary>
- /// 是否显示首页、尾页链接
- /// </summary>
- public bool ShowFirstLastPageLink { get; set; }
- /// <summary>
- /// 是否显示上一页、下一页链接
- /// </summary>
- public bool ShowPrevNextPageLink { get; set; }
- /// <summary>
- /// 是否显示数字按钮
- /// </summary>
- public bool ShowDigitalLink { get; set; }
- /// <summary>
- /// 数字按钮数量
- /// </summary>
- public int DigitalLinkCount { get; set; }
- /// <summary>
- /// 是否显示总记录数
- /// </summary>
- public bool ShowTotalRecord { get; set; }
- /// <summary>
- /// 总记录数出现位置
- /// </summary>
- public PagerElementPosition TotalRecordPosition { get; set; }
- /// <summary>
- /// 是否显示当前页数和总页数信息
- /// </summary>
- public bool ShowPageInfo { get; set; }
- /// <summary>
- /// 当前页和总页数信息显示位置
- /// </summary>
- public PagerElementPosition PageInfoPosition { get; set; }
- /// <summary>
- /// 是否显示GoTo输入区域
- /// </summary>
- public bool ShowGoTo { get; set; }
- /// <summary>
- /// 指定生成的元素对应的class的前缀字符
- /// </summary>
- public string CssClassPreWord { get; set; }
- /// <summary>
- /// 是否创建为ajax分页控件
- /// </summary>
- public bool UseAjax { get; set; }
- /// <summary>
- /// Ajax提交后更新的html元素id
- /// </summary>
- public string AjaxUpdateTargetID { get; set; }
- /// <summary>
- /// Ajax提交后调用的js function名称
- /// </summary>
- public string AjaxSuccessFunctionName { get; set; }
- /// <summary>
- /// 是否自动生成Ajax提交后调用的js function
- /// </summary>
- public bool AutoGenarateAjaxSuccessFunction { get; set; }
- /// <summary>
- /// 使用默认值初始化设置
- /// </summary>
- public PagerConfig()
- {
- PageSize = 20;
- RecordUnit = "条";
- RecordName = "记录";
- CurrentPageKey = "page";
- CssClassPreWord = "pager";
- ShowFirstLastPageLink = true;
- ShowPrevNextPageLink = true;
- ShowDigitalLink = true;
- DigitalLinkCount = 10;
- ShowTotalRecord = false;
- TotalRecordPosition = PagerElementPosition.Left;
- ShowPageInfo = false;
- PageInfoPosition = PagerElementPosition.Left;
- ShowGoTo = false;
- UseAjax = false;
- AjaxUpdateTargetID = "";
- AjaxSuccessFunctionName = "OnPageChanged";
- AutoGenarateAjaxSuccessFunction = true;
- }
- }
- #endregion
- /// <summary>
- /// 配合Pager扩展实现分页的帮助类
- /// </summary>
- public class PagerHelper
- {
- /// <summary>
- /// 获取记录开始和结束编号,并返回实际的页码
- /// </summary>
- /// <param name="allCount">记录总条数</param>
- /// <param name="pageSize">页大小</param>
- /// <param name="pageIndex">(输出)当前页码</param>
- /// <param name="startIndex">(输出)开始编号</param>
- /// <param name="endIndex">(输出)结束编号</param>
- /// <param name="currentPageKey">分页参数名称</param>
- /// <param name="pageIndexIs0Based">页码编号是否从0开始,默认为否</param>
- /// <param name="recordIndexIs0Based">记录编号是否从0开始,默认为否</param>
- public static void GetStartAndEndIndex(int allCount, int pageSize, out int pageIndex, out int startIndex, out int endIndex, string currentPageKey = "page", bool pageIndexIs0Based = false, bool recordIndexIs0Based = false)
- {
- //计算pageIndex的实际值
- pageIndex = GetRealPageIndex(allCount, pageSize, currentPageKey, pageIndexIs0Based);
- //计算过程是0based的
- if (!pageIndexIs0Based)
- {
- pageIndex--; //转成0based
- }
- //计算startIndex和endIndex
- startIndex = pageIndex * pageSize;
- endIndex = startIndex + pageSize - 1;
- if (endIndex > allCount - 1)
- {
- endIndex = allCount - 1;
- }
- //0based计算完成,下面根据设置不同,输出不同
- if (!pageIndexIs0Based)
- {
- pageIndex++;
- }
- if (!recordIndexIs0Based)
- {
- startIndex++;
- endIndex++;
- }
- }
- /// <summary>
- /// 返回实际页码
- /// </summary>
- /// <param name="allCount">总记录数</param>
- /// <param name="pageSize">页面大小</param>
- /// <param name="currentPageKey">分页参数名称</param>
- /// <param name="pageIndexIs0Based">页码编号是否从0开始,默认为否</param>
- /// <returns>实际页码</returns>
- public static int GetRealPageIndex(int allCount, int pageSize, string currentPageKey = "page", bool pageIndexIs0Based = false)
- {
- int pageIndex;
- //整个计算过程都是0based的
- if (pageSize < 1)
- {
- pageSize = 1; //容错
- }
- if (HttpContext.Current.Request.Params[currentPageKey] == null)
- {
- pageIndex = 0;
- }
- else
- {
- try
- {
- int _pageIndex = Convert.ToInt32(HttpContext.Current.Request.Params[currentPageKey]); //待判断的页码
- if (!pageIndexIs0Based)
- {
- _pageIndex--; //转成0based
- }
- if (_pageIndex < 0)
- {
- pageIndex = 0;
- }
- else
- {
- int totalPage = (int)Math.Ceiling(allCount / (double)pageSize);
- if (_pageIndex >= totalPage)
- {
- pageIndex = totalPage - 1;
- }
- else
- {
- pageIndex = _pageIndex;
- }
- }
- }
- catch
- {
- pageIndex = 0;
- }
- }
- //0based计算完成,下面根据设置不同,输出不同
- return (pageIndexIs0Based) ? pageIndex : pageIndex + 1;
- }
- }
- }
- namespace System.Web.Mvc.Html
- {
- public static class PagerExtensions
- {
- //提取 返回a标签 方法
- private static string getLinkHtml(UrlHelper urlHelper, bool useAjax, string ajaxSuccessFunction, string linkContent, string actionName, string controllerName, RouteValueDictionary routeValues)
- {
- string link = "";
- if (useAjax)
- {
- link += "<a href="javascript:$.post('" + urlHelper.Action(actionName, controllerName) + "',{";
- //将route放到post表单中
- foreach (var route in routeValues.Keys)
- {
- link += route + ":'" + routeValues[route].ToString() + "',";
- }
- if (routeValues.Count > 0)
- {
- link = link.Remove(link.Length - 1);
- }
- link += "}," + ajaxSuccessFunction + ")" >";
- }
- else
- {
- link += "<a href="" + urlHelper.Action(actionName, controllerName, routeValues) + "">";
- }
- link += linkContent;
- link += "</a>";
- return link;
- }
- #region 分页扩展
- /// <summary>
- /// 返回用于分页的div元素
- /// </summary>
- /// <param name="htmlHelper">HtmlHelper</param>
- /// <param name="pagerConfig">分页设置对象</param>
- /// <returns></returns>
- public static MvcHtmlString Pager(this HtmlHelper htmlHelper, PagerConfig pagerConfig)
- {
- return Pager(htmlHelper, "", "", new { }, new { }, pagerConfig);
- }
- /// <summary>
- /// 返回用于分页的div元素
- /// </summary>
- /// <param name="htmlHelper">HtmlHelper</param>
- /// <param name="htmlAttributes">html属性对象</param>
- /// <param name="pagerConfig">分页设置对象</param>
- /// <returns></returns>
- public static MvcHtmlString Pager(this HtmlHelper htmlHelper, object htmlAttributes, PagerConfig pagerConfig)
- {
- return Pager(htmlHelper, "", "", new { }, htmlAttributes, pagerConfig);
- }
- /// <summary>
- /// 返回用于分页的div元素
- /// </summary>
- /// <param name="htmlHelper">HtmlHelper</param>
- /// <param name="actionName">方法</param>
- /// <param name="htmlAttributes">html属性对象</param>
- /// <param name="pagerConfig">分页设置对象</param>
- /// <returns></returns>
- public static MvcHtmlString Pager(this HtmlHelper htmlHelper, string actionName, object htmlAttributes, PagerConfig pagerConfig)
- {
- return Pager(htmlHelper, actionName, "", new { }, htmlAttributes, pagerConfig);
- }
- /// <summary>
- /// 返回用于分页的div元素
- /// </summary>
- /// <param name="htmlHelper">HtmlHelper</param>
- /// <param name="actionName">方法</param>
- /// <param name="controllerName">控制器</param>
- /// <param name="htmlAttributes">html属性对象</param>
- /// <param name="pagerConfig">分页设置对象</param>
- /// <returns></returns>
- public static MvcHtmlString Pager(this HtmlHelper htmlHelper, string actionName, string controllerName, object htmlAttributes, PagerConfig pagerConfig)
- {
- return Pager(htmlHelper, actionName, controllerName, new { }, htmlAttributes, pagerConfig);
- }
- /// <summary>
- /// 返回用于分页的div元素
- /// </summary>
- /// <param name="htmlHelper">HtmlHelper</param>
- /// <param name="actionName">方法</param>
- /// <param name="controllerName">控制器</param>
- /// <param name="routeValues">路由参数</param>
- /// <param name="htmlAttributes">html属性对象</param>
- /// <param name="pagerConfig">分页设置对象</param>
- /// <returns></returns>
- public static MvcHtmlString Pager(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, object htmlAttributes, PagerConfig pagerConfig)
- {
- RouteValueDictionary RouteValues;
- if (routeValues == null)
- {
- RouteValues = new RouteValueDictionary();
- }
- else
- {
- RouteValues = new RouteValueDictionary(routeValues);
- }
- UrlHelper Url = new UrlHelper(htmlHelper.ViewContext.RequestContext);
- AjaxHelper Ajax = new AjaxHelper(htmlHelper.ViewContext, htmlHelper.ViewDataContainer);
- StringBuilder sbPager = new StringBuilder();
- sbPager.Append("<div");
- //利用反射获取htmlAttributes的全部元素和值
- if (htmlAttributes != null)
- {
- PropertyInfo[] htmlProperties = htmlAttributes.GetType().GetProperties();
- foreach (var property in htmlProperties)
- {
- sbPager.Append(" " + property.Name + "="" + property.GetValue(htmlAttributes).ToString() + """);
- }
- }
- sbPager.Append(">");
- //左侧记录总数信息
- if (pagerConfig.ShowTotalRecord && pagerConfig.PageInfoPosition == PagerElementPosition.Left)
- {
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-count">共" + pagerConfig.TotalRecord + pagerConfig.RecordUnit + pagerConfig.RecordName + "</span>");
- }
- //左侧页码信息
- if (pagerConfig.ShowPageInfo && pagerConfig.PageInfoPosition == PagerElementPosition.Left)
- {
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-info">第" + pagerConfig.CurrentPage + "页/共" + pagerConfig.TotalPage + "页</span>");
- }
- //首页
- if (pagerConfig.ShowFirstLastPageLink)
- {
- if (pagerConfig.CurrentPage > 1)
- {
- RouteValues[pagerConfig.CurrentPageKey] = 1;
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-btn">" + getLinkHtml(Url, pagerConfig.UseAjax, pagerConfig.AjaxSuccessFunctionName, "首页", actionName, controllerName, RouteValues) + "</span>");
- }
- else
- {
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-btn">首页</span>");
- }
- }
- //上一页
- if (pagerConfig.ShowPrevNextPageLink)
- {
- if (pagerConfig.CurrentPage > 1)
- {
- RouteValues[pagerConfig.CurrentPageKey] = pagerConfig.CurrentPage - 1;
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-btn">" + getLinkHtml(Url, pagerConfig.UseAjax, pagerConfig.AjaxSuccessFunctionName, "上一页", actionName, controllerName, RouteValues) + "</span>");
- }
- else
- {
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-btn">上一页</span>");
- }
- }
- //数字导航开始
- if (pagerConfig.ShowDigitalLink)
- {
- int shownStartPageIndex, shownEndPageIndex;
- //总页数少于要显示的页数,页码全部显示
- if (pagerConfig.DigitalLinkCount >= pagerConfig.TotalPage)
- {
- shownStartPageIndex = 1;
- shownEndPageIndex = pagerConfig.TotalPage;
- }
- else//显示指定数量的页码
- {
- int forward = (int)Math.Ceiling(pagerConfig.DigitalLinkCount / 2.0);
- if (pagerConfig.CurrentPage > forward)//起始页码大于1
- {
- shownEndPageIndex = pagerConfig.CurrentPage + pagerConfig.DigitalLinkCount - forward;
- if (shownEndPageIndex > pagerConfig.TotalPage)//结束页码大于总页码结束页码为最后一页
- {
- shownStartPageIndex = pagerConfig.TotalPage - pagerConfig.DigitalLinkCount + 1;
- shownEndPageIndex = pagerConfig.TotalPage;
- }
- else
- {
- shownStartPageIndex = pagerConfig.CurrentPage - forward + 1;
- }
- }
- else//起始页码从1开始
- {
- shownStartPageIndex = 1;
- shownEndPageIndex = pagerConfig.DigitalLinkCount;
- }
- }
- //向上…
- if (shownStartPageIndex > 1)
- {
- RouteValues[pagerConfig.CurrentPageKey] = shownStartPageIndex - 1;
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-number">" + getLinkHtml(Url, pagerConfig.UseAjax, pagerConfig.AjaxSuccessFunctionName, "...", actionName, controllerName, RouteValues) + "</span>");
- }
- //数字
- for (int i = shownStartPageIndex; i <= shownEndPageIndex; i++)
- {
- if (i != pagerConfig.CurrentPage)
- {
- RouteValues[pagerConfig.CurrentPageKey] = i;
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-number">" + getLinkHtml(Url, pagerConfig.UseAjax, pagerConfig.AjaxSuccessFunctionName, i.ToString(), actionName, controllerName, RouteValues) + "</span>");
- }
- else
- {
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-number " + pagerConfig.CssClassPreWord + "-currentnum">" + i.ToString() + "</span>");
- }
- }
- //向下…
- if (shownEndPageIndex < pagerConfig.TotalPage)
- {
- RouteValues[pagerConfig.CurrentPageKey] = shownEndPageIndex + 1;
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-number">" + getLinkHtml(Url, pagerConfig.UseAjax, pagerConfig.AjaxSuccessFunctionName, "...", actionName, controllerName, RouteValues) + "</span>");
- }
- }
- ////数字导航结束
- //下一页
- if (pagerConfig.ShowPrevNextPageLink)
- {
- if (pagerConfig.CurrentPage < pagerConfig.TotalPage)
- {
- RouteValues[pagerConfig.CurrentPageKey] = pagerConfig.CurrentPage + 1;
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-btn">" + getLinkHtml(Url, pagerConfig.UseAjax, pagerConfig.AjaxSuccessFunctionName, "下一页", actionName, controllerName, RouteValues) + "</span>");
- }
- else
- {
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-btn">下一页</span>");
- }
- }
- //尾页
- if (pagerConfig.ShowFirstLastPageLink)
- {
- if (pagerConfig.CurrentPage < pagerConfig.TotalPage)
- {
- RouteValues[pagerConfig.CurrentPageKey] = pagerConfig.TotalPage;
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-btn">" + getLinkHtml(Url, pagerConfig.UseAjax, pagerConfig.AjaxSuccessFunctionName, "尾页", actionName, controllerName, RouteValues) + "</span>");
- }
- else
- {
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-btn">尾页</span>");
- }
- }
- //右侧记录总数信息
- if (pagerConfig.ShowTotalRecord && pagerConfig.PageInfoPosition == PagerElementPosition.Right)
- {
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-count">共" + pagerConfig.TotalRecord + pagerConfig.RecordUnit + pagerConfig.RecordName + "</span>");
- }
- //右侧页码信息
- if (pagerConfig.ShowPageInfo && pagerConfig.PageInfoPosition == PagerElementPosition.Right)
- {
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-info">第" + pagerConfig.CurrentPage + "页/共" + pagerConfig.TotalPage + "页</span>");
- }
- //页码输入框
- if (pagerConfig.ShowGoTo)
- {
- RouteValues[pagerConfig.CurrentPageKey] = "--pageRouteValue--";
- sbPager.Append("<span class="" + pagerConfig.CssClassPreWord + "-goto">转到第<input class="" + pagerConfig.CssClassPreWord + "-goto-input" type="text" url="" + Url.Action(actionName, controllerName, RouteValues) + "" />页");
- if (pagerConfig.UseAjax)
- {
- sbPager.Append("<input class="" + pagerConfig.CssClassPreWord + "-goto-submit" type="button" value="GO" onclick="$.post( $(this).prev().attr('url').replace('--pageRouteValue--',$(this).prev().val())," + pagerConfig.AjaxSuccessFunctionName + ")" /></span>");
- }
- else
- {
- sbPager.Append("<input class="" + pagerConfig.CssClassPreWord + "-goto-submit" type="button" value="GO" onclick="window.location = $(this).prev().attr('url').replace('--pageRouteValue--',$(this).prev().val());" /></span>");
- }
- }
- //ajax分页回调函数
- if (pagerConfig.UseAjax)
- {
- if (pagerConfig.AutoGenarateAjaxSuccessFunction)
- {
- sbPager.Append("<script type="text/javascript">function " + pagerConfig.AjaxSuccessFunctionName + "(data){$('#" + pagerConfig.AjaxUpdateTargetID + "').html(data);}</script>");
- }
- }
- sbPager.Append("</div>");
- return MvcHtmlString.Create(sbPager.ToString());
- }
- #endregion
- }
- }
之前只实现了url分页,后来根据需要,又增加了ajax分页,ajax分页要配合一 个返回partialview的action来使用,具体就是调整调整useajax为true,调整AjaxUpdateTargetID,如果需要在 一个页面中多次使用分页控件,可能还需要用到AjaxSuccessFunctionName和 AutoGenarateAjaxSuccessFunction。几个分页控件如果使用相同的处理方法,只需要一个设置 AutoGenarateAjaxSuccessFunction为true即可,其余为false,如果分别用不同的处理方法,则设置每个 PagerConfig的AjaxSuccessFunctionName属性。
调用方法:
在controller利用PagerHelper实现分页:
- int pageSize = 20;
- int allCount = db.WebVideoCom_User.Count();
- ViewBag.Num = allCount;
- ViewBag.PageSize = pageSize;
- int pageIndex, startIndex, endIndex;
- //获取开始和结束的记录序号
- PagerHelper.GetStartAndEndIndex(allCount, pageSize, out pageIndex, out startIndex, out endIndex);
- //调用存储过程返回指定序号范围的数据
- return View(db.SelectUserList(startIndex, endIndex));