本文主要是介绍.Net MVC4 使用心得(三)实现分页控件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
之前写的,很凌乱,而且,几乎不粘代码,这不便于理解和也无法直接寻找可用代码。以后的文章会尽量引入代码实例。
这次需要一个翻页控件。之前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和endIndexstartIndex = 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\" οnclick=\"$.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\" οnclick=\"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));
view:
@Html.Pager(new PagerConfig { TotalRecord = ViewBag.Num, PageSize = ViewBag.PageSize })
然后只需要写写css就好了,关键是使用起来方便,这是我着手重写的主要原因
这样,终于把view解放了
这篇关于.Net MVC4 使用心得(三)实现分页控件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!