In this post, I will introduce how to write asp.net paging control. The reason is that at work, our project is a website project developed using the ancient asp.net technology. There is no suitable paging control, so I will write one myself.
Let’s first introduce the project environment. This is a website project more than 10 years ago, and now it is in the second phase of development. A paging control that has never been used before will be used in the webpage, and our original paging control is similar to this effect.
The Chinese characters in the above picture are: a total of 4642 records were retrieved, 50 records per page, page 1/93, first page, previous page, next page, last page, jump to page __ Jump.
The rendering of the new paging control is as follows:
How to write asp.net paging control
Well, based on the above introduction, we will officially start writing it. If you have experience in asp.net development, you should understand the concept of PostBack. Paging includes URL (query parameter) paging and PostBack-based paging. In essence, it is to post to the current page, and the server parses it from the post parameters. The query conditions can be obtained, and the corresponding data can be queried from the database.
So what are the complete steps to write a pagination control?
- write a paging control class and let it inherit the Panel control
- implement the IPostBackEventHandler interface
- implement the IPostBackDataHandler interface
- Define pagination event parameters
Let’s look at the complete code:
/// <summary> /// asp.net 分页控件 /// </summary> [ToolboxBitmap(typeof(AspNetPager), "AspNetPager.bmp")] [DefaultProperty("PageSize")] [DefaultEvent("PageChanged")] [ToolboxData("<{0}:AspNetPager runat=server></{0}:AspNetPager>")] public class AspNetPager : Panel, INamingContainer, IPostBackEventHandler, IPostBackDataHandler { private string inputPageIndex; private static readonly object EventPageChanging = new object(); private static readonly object EventPageChanged = new object(); private bool pageChangeEventHandled = false; /// <summary> /// 总页数 /// </summary> [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Browsable(false)] public int PageCount { get { if (TotalCount == 0) { return 1; } return (int)Math.Ceiling((double)TotalCount / (double)PageSize); } } /// <summary> /// 总记录数 /// </summary> [Bindable(true), Category("Default"), DefaultValue("0"), Description("总记录数")] [Localizable(true)] public long TotalCount { get { if (ViewState["TotalCount"] == null) return 0; long totalCount; long.TryParse(ViewState["TotalCount"].ToString(), out totalCount); return totalCount; } set { ViewState["TotalCount"] = value; } } /// <summary> /// 每页显示数据条数(页数据大小) /// </summary> [Bindable(true), Category("Default"), DefaultValue(50), Description("每页记录")] [Localizable(true)] public int PageSize { get { if (ViewState["PageSize"] == null) return 50; int pageSize; int.TryParse(ViewState["PageSize"].ToString(), out pageSize); return pageSize; } set { ViewState["PageSize"] = value; } } /// <summary> /// 当前页 /// </summary> [Bindable(true), Category("Default"), DefaultValue(1), Description("当前页")] [Localizable(true)] public int CurrentPageIndex { get { object obj = ViewState["CurrentPageIndex"]; int num = ((obj == null) ? 1 : ((int)obj)); if (num > PageCount && PageCount > 0) { return PageCount; } if (num < 1) { return 1; } return num; } set { int num = value; if (num < 1) { num = 1; } ViewState["CurrentPageIndex"] = num; if (!pageChangeEventHandled) { OnPageChanging(new PageChangingEventArgs(num)); } } } /// <summary> /// 布局位置 /// </summary> [Bindable(true), Category("Default"), DefaultValue(EnumDirection.Right), Description("布局位置")] [Localizable(true)] public EnumDirection Derection { get { if (ViewState["Derection"] == null) return EnumDirection.Right; EnumDirection derection; Enum.TryParse(ViewState["Derection"].ToString(), false, out derection); return derection; } set { ViewState["Derection"] = value; } } /// <summary> /// 页码变更触发事件 /// </summary> public event PageChangingEventHandler PageChanging { add { base.Events.AddHandler(EventPageChanging, value); } remove { base.Events.RemoveHandler(EventPageChanging, value); } } /// <summary> /// 页码改变后触发的事件 /// </summary> public event EventHandler PageChanged { add { base.Events.AddHandler(EventPageChanged, value); } remove { base.Events.RemoveHandler(EventPageChanged, value); } } /// <summary> /// 首次加载 /// </summary> /// <param name="e"></param> protected override void OnLoad(EventArgs e) { inputPageIndex = Page.Request.Form[UniqueID + "_input"]; if (!inputPageIndex.IsNullOrEmpty()) { pageChangeEventHandled = true; PageChangingEventArgs er = new PageChangingEventArgs(inputPageIndex.CastTo<int>()); OnPageChanging(er); pageChangeEventHandled = false; } var pageSize = Page.Request.Form[$"{this.UniqueID}_pagesize"].CastTo<int>(); if (pageSize > 0 && PageSize != pageSize) { pageChangeEventHandled = true; PageSize = pageSize; PageChangingEventArgs er = new PageChangingEventArgs(1); OnPageChanging(er); pageChangeEventHandled = false; } base.OnLoad(e); } /// <summary> /// 加载post请求数据 /// </summary> /// <param name="postDataKey"></param> /// <param name="postCollection"></param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> public bool LoadPostData(string postDataKey, NameValueCollection postCollection) { string text = postCollection[UniqueID + "_input"]; if (text != null && text.Trim().Length > 0) { try { int num = int.Parse(text); if (num > 0 && num <= PageCount) { inputPageIndex = text; Page.RegisterRequiresRaiseEvent(this); } } catch { } } return false; } /// <summary> /// 处理回发事件 /// </summary> /// <param name="args"></param> /// <exception cref="NotImplementedException"></exception> public void RaisePostBackEvent(string args) { int newPageIndex = CurrentPageIndex; try { if (string.IsNullOrEmpty(args)) { args = inputPageIndex; } newPageIndex = int.Parse(args); } catch { } PageChangingEventArgs e = new PageChangingEventArgs(newPageIndex); OnPageChanging(e); } /// <summary> /// 处理post数据变更事件 /// </summary> public virtual void RaisePostDataChangedEvent() { } /// <summary> /// 页码变更事件 /// </summary> /// <param name="e"></param> protected virtual void OnPageChanging(PageChangingEventArgs e) { pageChangeEventHandled = true; PageChangingEventHandler pageChangingEventHandler = (PageChangingEventHandler)base.Events[EventPageChanging]; if (pageChangingEventHandler != null) { pageChangingEventHandler(this, e); if (!e.Cancel) { CurrentPageIndex = e.CurrPage; OnPageChanged(EventArgs.Empty); } } else { CurrentPageIndex = e.CurrPage; OnPageChanged(EventArgs.Empty); } pageChangeEventHandled = false; } /// <summary> /// 页码变更后触发事件 /// </summary> /// <param name="e"></param> protected virtual void OnPageChanged(EventArgs e) { EventHandler eventHandler = (EventHandler)base.Events[EventPageChanged]; if (eventHandler != null) { eventHandler(this, e); } } /// <summary> /// 准备呈现控件 /// </summary> /// <param name="e"></param> protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); } /// <summary> /// 呈现控件内容 /// </summary> /// <param name="writer"></param> protected override void RenderContents(HtmlTextWriter writer) { writer.WriteLine($"<div style=\"width:100%;text-align:{Derection.ToDescription()};margin:5px 0px;\">"); writer.Write($"共检索到 {TotalCount} 条记录,每页 {PageSize} 条,第 {CurrentPageIndex}/{PageCount} 页 "); StringBuilder sb = new StringBuilder(200); for (int i = 1; i <= 10; i++) { string selected = (PageSize / 10) == i ? "selected=\"selected\"" : ""; sb.AppendFormat("<option value=\"{0}\" title=\"每页显示 {0} 条\" {1}>{0}条/页</option>", i * 10, selected); } writer.Write($"<select class=\"pageselect\" name=\"{this.UniqueID}_pagesize\" onchange=\"__doPostBack('{this.UniqueID}_pagesize',this.value)\">{sb}</select>"); long num = (int)Math.Ceiling((double)TotalCount / (double)PageSize); long currentPage = CurrentPageIndex; if (num < currentPage) currentPage = 1; long num4 = ((currentPage + 5) > num) ? (num - 9) : (currentPage - 4); long num5 = (currentPage < 5) ? 10 : (currentPage + 5); if (num4 < 1) num4 = 1; if (num < num5) num5 = num; if (currentPage > 1) { var href = Page.ClientScript.GetPostBackClientHyperlink(this, "1"); writer.Write($"<a href=\"{href}\" style='color:red'>首页</a>"); href = Page.ClientScript.GetPostBackClientHyperlink(this, (currentPage - 1).ToString()); writer.Write($"<a href=\"{href}\" style='color:red'><</a>"); } else { writer.Write($"<a href=\"###\" style='color:red' onclick=\"alert('已经是第1页了')\">首页</a>"); writer.Write($"<a href=\"###\" style='color:red' onclick=\"alert('不能向前翻了')\"><</a>"); } for (var i = num4; i <= num5; i++) { var href = Page.ClientScript.GetPostBackClientHyperlink(this, i.ToString()); if (currentPage == i) { writer.Write($"<a href=\"{href}\" style='color:red'>{i}</a>"); } else { writer.Write($"<a href=\"{href}\">{i}</a>"); } } if (currentPage != num) { var href = Page.ClientScript.GetPostBackClientHyperlink(this, (currentPage + 1).ToString()); writer.Write($"<a href=\"{href}\" style='color:red'>></a>"); href = Page.ClientScript.GetPostBackClientHyperlink(this, num.ToString()); writer.Write($"<a href=\"{href}\" style='color:red'>末页</a>"); } else { writer.Write($"<a href=\"javascript:alert('不能向后翻了')\">></a>"); writer.Write($"<a href=\"###\" style='color:red' onclick=\"alert('已经最后一页了')\">末页</a>"); } writer.Write($" 跳至 <input type=\"text\" id=\"{UniqueID}_input\" name=\"{UniqueID}_input\" /> 页 "); writer.Write($"<input type=\"button\" name=\"{UniqueID}_Jump\" value=\"跳 转\" onclick=\"__doPostBack('{UniqueID}_Jump',document.getElementById('{UniqueID}_input').value)\" />"); writer.WriteLine("</div>"); } } /// <summary> /// 页码改变委托 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public delegate void PageChangingEventHandler(object sender, PageChangingEventArgs e); /// <summary> /// 分页事件参数 /// </summary> public sealed class PageChangingEventArgs : CancelEventArgs { private readonly int _newpageindex; /// <summary> /// 当前页 /// </summary> public int CurrPage { get { return _newpageindex; } } /// <summary> /// 分页事件参数构造函数 /// </summary> /// <param name="currPage">当前页</param> public PageChangingEventArgs(int currPage) { _newpageindex = currPage; } }
How to write asp.net paging control
The final effect is as follows:
I didn’t add any styles, you can add styles to make it more beautiful.