以前在ASP.NET WebForm开发中会用到许多控件,像DropDownList等。同样ASP.NET MVC中也有类似的控件-HtmlHelper。
HtmlHelper和服务器控件相比,HtmlHelper更灵活一些,而且扩展起来也更方便。实际开发中“分页”功能是必不可少的,于是我自定义了一个HtmlHelper的分页控件,总结出来,希望能帮助到大家。
HtmlHelper扩展方式有两种:
1.@helper
这种方式是使用Razor语法扩展。直接在cshtml中编写即可,非常直观。它有两种实现形式:
- 直接在当前cshtml中编写,然后直接调用:
<h2>Demo</h2> @helper MyButton(string name,string style){ //todo: 实现 } <div> @MyButton("呵呵","margin:3px 3px;") </div>
- 在单独的cshtml中编写,在其他文件中调用,这个cshtml文件必须放在App_Code里面:
<h2>Demo1</h2> <div> @hHelpers.MyButton("哈哈","Color:red;") </div>
2.扩展方法利用C#特性-扩展方法来实现扩展,本文将采用这种方式。废话不多说直接上代码。首先先定义一个PageViewData类,用于存储分页的相关信息
public class PageViewData<T> { /// <summary> /// 当前页 /// </summary> public int CurrentPage { get; set; } private readonly int _totalPageount; /// <summary> /// 总页数 /// </summary> public int TotalPageCount { get { return _totalPageount; } } private int _totalDataCount; /// <summary> /// 数据源总量 /// </summary> public int TotalDataCount { get { return _totalDataCount; } set { _totalDataCount = value; } } private int _pageSize; /// <summary> /// 每页显示数据大小 /// </summary> public int PageSize { get { return _pageSize; } set { _pageSize = value; } } /// <summary> /// 当前页数据列表 /// </summary> public IList<T> Items { get; set; } public PageViewData() { } public PageViewData(int currentPage, int pageSize, int totalDataCount) { CurrentPage = currentPage; _pageSize = pageSize; _totalDataCount = totalDataCount; _totalPageount = (int)Math.Ceiling(_totalDataCount * 1.0 / _pageSize); } }
然后开始编写分页组件代码。
public static MvcHtmlString PagePanel<T>(this HtmlHelper html, PageViewData<T> pageViewData, Func<int, string> action, int showMaxPageCount = 10, PagingMode mode = PagingMode.Plain) { if (showMaxPageCount <= 0) { return MvcHtmlString.Empty; } StringBuilder sb = new StringBuilder(); sb.AppendFormat("<div id="kPaging">"); if (pageViewData.TotalPageCount > 1) { if (mode == PagingMode.Detail) { sb.AppendFormat("<span style="margin:0px 5px;">第 {0} 页,共{1}页,共{2}条</span>", pageViewData.TotalPageCount < pageViewData.CurrentPage ? 1 : pageViewData.CurrentPage, pageViewData.TotalPageCount, pageViewData.TotalDataCount); } int startPageNum, endPageNum; sb.AppendFormat(PageLinkTemplete, action(1), "首页"); if (pageViewData.CurrentPage > 1) { sb.AppendFormat(PageLinkTemplete, action(pageViewData.CurrentPage - 1), "上一页"); } //第一页 if (pageViewData.CurrentPage <= 1) { startPageNum = 1; endPageNum = showMaxPageCount; if (endPageNum > pageViewData.TotalPageCount) { endPageNum = pageViewData.TotalPageCount; } pageViewData.CurrentPage = 1; } else if (pageViewData.CurrentPage >= pageViewData.TotalPageCount)//最后一页 { startPageNum = pageViewData.TotalPageCount - showMaxPageCount + 1; endPageNum = pageViewData.TotalPageCount; if (startPageNum <= 0) { startPageNum = 1; } pageViewData.CurrentPage = pageViewData.TotalPageCount; } else { //当前页区域 int regionIndex = 1; regionIndex = (int)Math.Ceiling(pageViewData.CurrentPage * 1.0 / showMaxPageCount); startPageNum = (regionIndex - 1) * showMaxPageCount + 1; endPageNum = regionIndex * showMaxPageCount; //TotalPageCount是否小于endPageNum if (endPageNum > pageViewData.TotalPageCount) { endPageNum = pageViewData.TotalPageCount; } } for (int i = startPageNum; i <= endPageNum; i++) { if (i == pageViewData.CurrentPage) { sb.AppendFormat(CurrentPageLinkTemplete, i); } else { sb.AppendFormat(PageLinkTemplete, action(i), i); } } if (pageViewData.CurrentPage < pageViewData.TotalPageCount) { sb.AppendFormat(PageLinkTemplete, action(pageViewData.CurrentPage + 1), "下一页"); } sb.AppendFormat(PageLinkTemplete, action(pageViewData.TotalPageCount), "末页"); } sb.AppendFormat("</div>"); return MvcHtmlString.Create(sb.ToString()); }
最后调用
<style type="text/css"> #kPaging { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; FONT-SIZE: 0.85em; PADDING-BOTTOM: 3px; MARGIN: 3px; PADDING-TOP: 3px; FONT-FAMILY: Tahoma,Helvetica,sans-serif; TEXT-ALIGN: center; } #kPaging .currentPage { PADDING-RIGHT: 6px; PADDING-LEFT: 6px; FONT-WEIGHT: bold; PADDING-BOTTOM: 2px; COLOR: #000; MARGIN-RIGHT: 3px; PADDING-TOP: 2px; } #kPaging .pageLink { BORDER-RIGHT: #ccdbe4 1px solid; PADDING-RIGHT: 8px; BACKGROUND-POSITION: 50% bottom; BORDER-TOP: #ccdbe4 1px solid; PADDING-LEFT: 8px; PADDING-BOTTOM: 2px; BORDER-LEFT: #ccdbe4 1px solid; COLOR: #0061de; MARGIN-RIGHT: 3px; PADDING-TOP: 2px; BORDER-BOTTOM: #ccdbe4 1px solid; TEXT-DECORATION: none; } </style> <h2>title</h2> @Html.PagePanel(new PageViewData<Student>(6, 10, 58), i => string.Format("#?page={0}", i), 10)
展示效果:
它的样式我们可以自定义,只要重写#kPaging、.pageLink、.currentPage选择器内容即可。