日期:2014-05-20  浏览次数:20451 次

又有新成果分享给大家了:一个和Ajax配合使用的轻量级无刷新分页控件
我设计此控件的背景思想:
既然我想做一个无刷新分页控件,那我觉得该控件就只需要关心如下几个因素:
1)总共有多少条记录;
2)每页多少条;
3)当前第几页;

而不需要关心如点击某个页码时,该如何去获取数据。如果连如何去获取数据的逻辑都要由该控件来实现的话,那此控件的独立性就不好了。以前我见过一些页面重定向的分页控件,此类控件都需要在当前url的基础上再添加一个PageIndex的url参数。这就使得分页控件需要关心当前url的地址。而如果借助于Ajax技术,由于页面是无刷新的,所以我想是否可以设计一个控件,该控件只负责根据上面的三个信息,生成所有相关的页码,每个页码点击时执行一个由用户指定的javascript函数,并把被点击页的页码传给该函数,然后在该javascript函数中,用户可以利用ajax技术根据自己的业务逻辑获取当前页的数据。所以,这样以来,我们就可以完全做到让分页控件只负责实现如何分页的逻辑,其他的一概不用关心;这样不是很好吗?哈哈。

控件特点:
1)代码简洁清晰,轻量级,尽量不包含任何多余的东西,这也是我一贯的作风;(为了能让大家更好更快的理解,我特地耐心的加了注释)
2)需要和无刷新技术(如Ajax)结合使用,并且需要配合一个javascript客户端分页函数,(比如TurnPage)

以下是源代码:
C# code

/// <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
}