ASP.NET分頁

效果 pager

前臺頁面代碼(MyPager.ascx):javascript

<asp:PlaceHolder ID="holder" runat="server"></asp:PlaceHolder>

後臺頁面代碼(MyPager.ascx.cs):html

public partial class MyPager : System.Web.UI.UserControl
    {
        private int pageSize;      //默認每頁多少條記錄
        private int totalCount = 0;     //默認總記錄數
        private int totalPage;          //總頁數
        private int currentPage = 1;    //默認當前是第幾頁
        private int offsetCount = 4;    //默認偏移量

        private string url;

        /// <summary>
        /// 總記錄數
        /// </summary>
        public int TotalCount
        {
            get { return totalCount; }
            set { totalCount = value; }
        }

        /// <summary>
        /// 頁容量
        /// </summary>
        public int PageSize
        {
            get { return pageSize; }
            set { pageSize = value; }
        }

        /// <summary>
        /// 當前頁
        /// </summary>
        public int CurrentPage
        {
            get { return currentPage; }
            set { currentPage = value; }
        }

        /// <summary>
        /// div的樣式
        /// </summary>
        public string CssClass
        {
            get;
            set;
        }

        /// <summary>
        /// 當前頁顯示的樣式
        /// </summary>
        public string CurrentPageCssClass
        {
            get;
            set;
        }

        private bool showSinglePage = false;
        /// <summary>
        /// 若是總頁數只有1, 是否顯示(默認不顯示)
        /// </summary>
        public bool ShowSinglePage
        {
            get { return showSinglePage; }
            set { showSinglePage = value; }
        }

        /// <summary>
        /// 重載OnInit事件, 介樣, 內容頁面(Page_Load)就能夠直接獲得CurrentPage和PageSize參數
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            int tmpPage = 1;

            //獲取當前頁
            if (int.TryParse(Request.Params.Get("page"), out tmpPage) && tmpPage > 0)
            {
                currentPage = tmpPage;
            }

            //獲取pagesize
            GetPageSize();

            //生成連接
            GetUrl();

            base.OnInit(e);
        }

        /// <summary>
        /// 因爲頁面的執行順序是Page_Load, Control_Event, Page_PreRender, 
        /// 因此若是將 CreatePage()方法放在Page_Load中, 那麼分頁控件將沒法準確執行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_PreRender(object sender, EventArgs e)
        {
            holder.Controls.Clear();

            var wrapper = new HtmlGenericControl("div");
            wrapper.Attributes["id"] = ClientID;
            wrapper.Attributes["class"] = this.CssClass;

            //建立連接, 並附加到wrapper中
            this.CreatePage(wrapper);

            //若是有子元素, 那麼將其附加到placeholder中
            if (wrapper.Controls.Count > 0)
                holder.Controls.Add(wrapper);

            //base.OnPreRender(e);
        }

        /// <summary>
        /// 獲取pageSize
        ///  1, 試圖從url中獲得pagesize參數
        ///  2, 若是1不行, 那麼試圖從cookie中獲得該參數
        ///  3, 若是2不行, 那麼就會從config中獲得該值
        /// </summary>
        /// <param name="tmpPagesize"></param>
        /// <returns></returns>
        private void GetPageSize()
        {
            int tmpPagesize = 10;

            if (int.TryParse(Request.QueryString.Get("pagesize"), out tmpPagesize) && tmpPagesize > 0)
            {
                pageSize = tmpPagesize;

                //若是檢測到cookie中有pagesize, 那麼就更新
                var rqSize = Request.Cookies.Get("pagesize");
                if (rqSize == null)
                {
                    var cookie = new System.Web.HttpCookie("pagesize", pageSize.ToString());
                    Response.Cookies.Add(cookie);
                }
                else if (rqSize != null && rqSize.Value != pageSize.ToString())
                {
                    rqSize.Value = pageSize.ToString();
                    Response.SetCookie(rqSize);
                }

                return;
            }
            else if (pageSize <= 0)
            {
                pageSize = PubUtility.WebParameter.Parm_GVlines;
            }

        }

        /// <summary>
        /// 獲得當前頁面的全部參數, 而且重組成一個去掉page參數的url
        /// </summary>
        private void GetUrl()
        {
            
            string url = Request.Path+"?";

            if (Request.QueryString.Count < 1)
            {
                this.url = url;
                return;
            }

            foreach (string k in Request.QueryString.Keys)
            {
                //去除url中的page參數
                if (k == "page" || string.IsNullOrWhiteSpace(k)) continue;
                url += k + "=" + Server.UrlEncode(Request.QueryString[k]) + "&";
            }

            this.url = url;
        }

        /// <summary>
        /// 生成翻頁的連接
        /// </summary>
        private void CreatePage(HtmlGenericControl father)
        {
            var ctrl = father.Controls;

            totalPage = (int)Math.Ceiling(TotalCount / (PageSize + 0.0));// +TotalCount % PageSize;

            //若是總頁數只有1頁, 而且showSinglePage==false, 那麼啥也不作
            if (!showSinglePage && totalPage == 1) return;

            //過濾掉不正常的CurrentPage, 好比當前頁比總頁數還要大, 或者是負數等等
            //固然這裏過濾顯然已經晚了, 由於此時是在頁面預呈現的時候生成的html, 在這以前(沒有通過驗證的)CurrentPage可能已經被利用了
            currentPage = Math.Min(currentPage, totalPage);
            currentPage = Math.Max(currentPage, 1);

            //左邊/右邊偏移量
            //正常狀況下 翻頁數應當從offsetLeft開始, 到offsetRight結束
            //可是還須要考慮些特殊狀況, 好比左偏移小於1, 或者右偏移大於總頁數
            int offsetLeft = Math.Max((currentPage - offsetCount), 1);
            int offsetRight = Math.Min((currentPage + offsetCount), totalPage);

            //使分頁更加整齊
            if ((offsetRight - offsetLeft) <= 2 * offsetCount)
            {
                offsetRight = Math.Min((2 * offsetCount + offsetLeft), totalPage);
                offsetLeft = Math.Max((offsetRight - 2 * offsetCount), 1);
            }

            //又使分頁更加整齊了, 這句代碼徹底能夠幹掉
            if (offsetLeft == 1)
                offsetRight = Math.Min((offsetRight + 1), totalPage);

            //噹噹前頁大於1的時候顯示上一頁
            if (currentPage > 1) ctrl.Add(SetHyperLink(currentPage - 1, "上一頁"));

            //當左偏移量大於1的時候顯示第一頁
            if (offsetLeft > 1) ctrl.Add(SetHyperLink(1, "1"));
            if (offsetLeft > 2) ctrl.Add(SetSpan());

            for (var i = offsetLeft; i <= offsetRight; i++)
            {
                if (i == currentPage)
                {
                    ctrl.Add(SetHyperLink(null, i.ToString(), CurrentPageCssClass));
                    continue;
                }
                ctrl.Add(SetHyperLink(i, i.ToString()));
            }

            //當右偏移量比總頁數小的時候顯示最後一頁
            if (offsetRight < totalPage - 1) ctrl.Add(SetSpan());
            if (offsetRight < totalPage) ctrl.Add(SetHyperLink(totalPage, totalPage.ToString()));

            //下一頁
            if (currentPage < totalPage) ctrl.Add(SetHyperLink(currentPage + 1, "下一頁"));

        }

        private HtmlAnchor SetHyperLink(int page)
        {
            return this.SetHyperLink(page, page.ToString());
        }

        private HtmlAnchor SetHyperLink(int page, string name)
        {
            return this.SetHyperLink(page, name, null);
        }

        private HtmlAnchor SetHyperLink(int? page, string name, string className)
        {
            string url = page == null
                ? "javascript:void(0);"
                : (this.url + "page=" + page);

            HtmlAnchor a = new HtmlAnchor();
            a.InnerText = name;
            a.HRef = url;

            if (!string.IsNullOrEmpty(className))
                a.Attributes["class"] = className;

            return a;
        }

        private HtmlGenericControl SetSpan(string innerHTML = "...")
        {
            var span = new HtmlGenericControl("span");
            span.InnerHtml = innerHTML;
            return span;
        }

    }
相關文章
相關標籤/搜索