我设计此控件的背景思想:
既然我想做一个无刷新分页控件,那我觉得该控件就只需要关心如下几个因素:
1)总共有多少条记录;
2)每页多少条;
3)当前第几页;而不需要关心如点击某个页码时,该如何去获取数据。如果连如何去获取数据的逻辑都要由该控件来实现的话,那此控件的独立性就不好了。以前我见过一些页面重定向的分页控件,此类控件都需要在当前url的基础上再添加一个PageIndex的url参数。这就使得分页控件需要关心当前url的地址。而如果借助于Ajax技术,由于页面是无刷新的,所以我想是否可以设计一个控件,该控件只负责根据上面的三个信息,生成所有相关的页码,每个页码点击时执行一个由用户指定的javascript函数,并把被点击页的页码传给该函数,然后在该javascript函数中,用户可以利用ajax技术根据自己的业务逻辑获取当前页的数据。所以,这样以来,我们就可以完全做到让分页控件只负责实现如何分页的逻辑,其他的一概不用关心;这样不是很好吗?哈哈。控件特点:
1)代码简洁清晰,轻量级,尽量不包含任何多余的东西,这也是我一贯的作风;(为了能让大家更好更快的理解,我特地耐心的加了注释)
2)需要和无刷新技术(如Ajax)结合使用,并且需要配合一个javascript客户端分页函数,(比如TurnPage)以下是源代码:/// <summary>
/// An simple and utility ajax pager.
/// </summary>
public class AjaxPager : Control
{
    #region Private Members    private string pageHref = "<a href={1}>{0}</a>";
    private string turnPage = "javascript:{0}({1});";
    private string seperatorSpace = "  ";    #endregion    #region Public Properties    /// <summary>
    /// The min value is 1.
    /// </summary>
    public int PageIndex
    {
        get
        {
            int pageIndex = 1;
            int? nullableIntegerValue = GetNullableIntegerValue("PageIndex");
            if (nullableIntegerValue.HasValue)
            {
                pageIndex = nullableIntegerValue.Value;
            }
            if (pageIndex < 1)
            {
                pageIndex = 1;
            }
            return pageIndex;
        }
        set
        {
            ViewState["PageIndex"] = value;
        }
    }
    /// <summary>
    /// The min value is 1.
    /// </summary>
    public int PageSize
    {
        get
        {
            int pageSize = 20;  //Set the default value.
            int? nullableIntegerValue = GetNullableIntegerValue("PageSize");
            if (nullableIntegerValue.HasValue)
            {
                pageSize = nullableIntegerValue.Value;
            }
            if (pageSize < 1)
            {
                pageSize = 1;
            }
            return pageSize;
        }
        set
        {
            ViewState["PageSize"] = value;
        }
    }
    /// <summary>
    /// This property indicates the length of the pager. That means how many page numbers the pager should display.
    /// E.g. PageLength = 7 means the pager can most display 7 page numbers. 1,2,3,4,5,6,7 or 30,31,32,33,34,45,36
    /// Notes: The PageLength should be an Odd number, like 1,3,5,7,9,11,etc.
    /// The default value is 5, and the minimum value is 3.
    /// </summary>
    public int PageLength
    {
        get
        {
            int pageLength = 5;  //Set the default value.
            int? nullableIntegerValue = GetNullableIntegerValue("PageLength");
            if (nullableIntegerValue.HasValue)
            {
                pageLength = nullableIntegerValue.Value;
            }
            if (pageLength < 3)
            {
                return 3;
            }
            if (pageLength % 2 == 0)
            {
                return pageLength + 1;
            }
            return pageLength;
        }
        set
        {
            ViewState["PageLength"] = value;
        }
    }
    /// <summary>
    /// This property indicates the total page number.
    /// </summary>
    public int TotalPages
    {
        get
        {
            return CalculateTotalPages(TotalRecords);
        }
    }
    /// <summary>
    /// This property indicates the total record count.
    /// </summary>
    public int TotalRecords
    {
        get
        {
            int totalRecords = 0;
            int? nullableIntegerValue = GetNullableIntegerValue("TotalRecords");
            if (nullableIntegerValue.HasValue)
            {
                totalRecords = nullableIntegerValue.Value;
            }
            return totalRecords;
        }
        set
        {
            ViewState["TotalRecords"] = value;
        }
    }
    /// <summary>
    /// This property represents an client javascript function name.
    /// This javascript function will be called when the page number is clicked.
    /// </summary>
    public string TurnPageClientFunction
    {
        get
        {
            return ViewState["TurnPageClientFunction"] as string;
        }
        set
        {
            ViewState["TurnPageClientFunction"] = value;
        }
    }    #endregion    #region Overrides Methods    /// <summary>
    /// Overrides this function to render all the paging items.
    /// </summary>
    protected override void Render(HtmlTextWriter writer)
    {
        if (TotalPages <= 1)
        {
            return;
        }        StringBuilder sb = new StringBuilder();        //append the first page.
        if ((PageIndex > PageLength / 2 + 1) && (TotalPages > PageLength))
        {
            sb.Append(CreatePageHref("第一页", 1));
        }
        sb.Append(seperatorSpace);        //append the previous page.
        if (PageIndex > 1)
        {
            sb.Append(CreatePageHref("上一页", PageIndex - 1));
        }
        sb.Append(seperatorSpace);        //append the number pages.
        sb.Append(GetNumberPages());        //append the next page.
        if (PageIndex < TotalPages)
        {
            sb.Append(CreatePageHref("下一页", PageIndex + 1));
        }
        sb.Append(seperatorSpace);        //append the last page.
        if (((PageIndex + PageLength / 2) < TotalPages) && (TotalPages > PageLength))
        {
            sb.Append(CreatePageHref("最后一页", TotalPages));
        }        //write the total contents.
        writer.Write(sb.ToString());
    }    #endregion    #region Private Methods    /// <summary>
    /// This function used to create the href attribute value of the A html tag.
    /// </summary>
    private string CreatePageHref(string text, int pageIndex)
    {
        //Check whether the client side turn page javascript function is null
        //If null, then we just return the text of the page item.
        if (string.IsNullOrEmpty(TurnPageClientFunction))
        {
            return text;
        }
        return string.Format(pageHref, text, string.Format(turnPage, TurnPageClientFunction, pageIndex));
    }
    /// <summary>
    /// This function used to render all the paging numbers. Like: 1,2,3,4,5
    /// </summary>
    private string GetNumberPages()
    {
        int totalPages = TotalPages;
        int pageIndex = PageIndex;
        int pageLength = PageLength;        //First, calculate the startIndex and endIndex.
        int startIndex = pageIndex - pageLength / 2;
        int endIndex = pageIndex + pageLength / 2;        if (startIndex < 1)
        {
            endIndex += 1 - startIndex;
            startIndex = 1;
        }
        if (endIndex > totalPages)
        {
            startIndex -= endIndex - totalPages;
            endIndex = totalPages;
        }
        if (startIndex < 1)
        {
            startIndex = 1;
        }
        if (endIndex > totalPages)
        {
            endIndex = totalPages;
        }        //Second, render all the paging numbers.
        StringBuilder sb = new StringBuilder();
        for (int i = startIndex; i <= endIndex; i++)
        {
            if (pageIndex == i)
            {
                sb.Append("[" + i.ToString() + "]");
            }
            else
            {
                sb.Append(CreatePageHref("[" + i.ToString() + "]", i));
            }
            if (i < endIndex)
            {
                sb.Append(seperatorSpace);
            }
        }
        return sb.ToString();
    }
    /// <summary>
    /// This function used to calculate the total pages.
    /// </summary>
    private int CalculateTotalPages(int totalRecords)
    {
        int totalPages;        if (totalRecords == 0)
        {
            return 0;
        }        totalPages = totalRecords / PageSize;        if ((totalRecords % PageSize) > 0)
        {
            totalPages++;
        }        return totalPages;
    }
    /// <summary>
    /// This function used to return a nullable integer value from the ViewState with the specified view state key.
    /// </summary>
    private int? GetNullableIntegerValue(string viewStateKey)
    {
        int? value = null;
        if (!string.IsNullOrEmpty(viewStateKey) && ViewState[viewStateKey] != null)
        {
            int tempValue = 0;
            if (int.TryParse(ViewState[viewStateKey].ToString(), out tempValue))
            {
                value = tempValue;
            }
        }
        return value;
    }    #endregion
}

解决方案 »

  1.   

    由于一次性文字内容过长,所以剩下的就写在回复里了:
    在前台调用该控件的代码:<nwap:AjaxPager ID="pager" TurnPageClientFunction="TurnPage" PageSize="30" runat="server" />
    TurnPage javascript函数的实现://The following two functions are the TurnPage function and its callback function.
    function TurnPage(pageIndex)
    {
        var keyTitle = document.getElementById('previousKeyTitleHidden').value;   
        var provinceId = document.getElementById('previousProvinceIdHidden').value;
        var cityId = document.getElementById('previousCityIdHidden').value;
        var townId = document.getElementById('previousTownIdHidden').value;
        var smallTownId = document.getElementById('previousSmallTownIdHidden').value;
        var auctionDate = document.getElementById('previousAuctionDateHidden').value;    AjaxMethods.SearchAuctions('<%= ClientID %>', keyTitle, provinceId, cityId, townId, smallTownId, auctionDate, pageIndex, TurnPageCallBack)
    }
    function TurnPageCallBack(result)
    {
        if(result.error != null && result.error != "")
        {
            alert(result.error);
            return;
        }
        document.getElementById('auctionDisplayContainer').innerHTML = result.value.AuctionList;
        document.getElementById('currentPageContainer').innerHTML = result.value.CurrentPage;
        document.getElementById('pagerContainer').innerHTML = result.value.Pager;
    }
    其中AjaxMethods.SearchAuctions这里实在通过Ajax调用服务器端的接口来获取当前页的数据。回调函数TurnPageCallBack则负责更新UI。差不多了,我的主要目的还是想为了和大家分享我新写的这个分页控件的源代码,希望大家能看看,并给我些意见让我能改进。
      

  2.   

    似乎CSDN的发帖编辑器有bug,为什么我本来想将字体设置为红色的,为什么却原样显示了呢:
    TurnPage
    AjaxMethods.SearchAuctions
    TurnPageCallBack
      

  3.   

    似乎CSDN的发帖编辑器有bug,为什么我本来想将字体设置为红色的,为什么却原样显示了呢: TurnPage
    AjaxMethods.SearchAuctions
    TurnPageCallBack
      

  4.   

    大哥,cnblogs不知道出了多少这种东东,都封装好了,该测的都测了。
      

  5.   

    hao  dongxi   kan  kan