Wednesday, November 25, 2009

Custom Pagination Class in asp.net

The following example will illustrate about custom pagination using a class ,

In your aspx page:

<asp:GridView ID="GridView1" runat="server">
        </asp:GridView>
      
        <br />
        <asp:Label ID="lblCurrentPage" runat="server" Visible="false"></asp:Label>
        <div id="pageIndexer" runat="server" class="pager">
            <asp:LinkButton id="btnFirst" runat="server" Text=" First " CssClass="page-numbers prev" onCommand="Nav_OnClick" CommandName="First"  />
            <asp:LinkButton id="btnPrev" runat="server" Text=" Prev " CssClass="page-numbers prev" onCommand="Nav_OnClick" CommandName="Prev"  />
            <asp:LinkButton ID="lnkbtn0" CssClass="page-numbers" runat="server" onCommand="Nav_OnClick" CommandName="Page" />
            <asp:LinkButton ID="lnkbtn1" CssClass="page-numbers" runat="server" onCommand="Nav_OnClick" CommandName="Page" />
            <asp:LinkButton ID="lnkbtn2" CssClass="page-numbers" runat="server" onCommand="Nav_OnClick" CommandName="Page" />
            <asp:LinkButton ID="lnkbtn3" CssClass="page-numbers" runat="server" onCommand="Nav_OnClick" CommandName="Page" />
            <asp:LinkButton ID="lnkbtn4" CssClass="page-numbers" runat="server" onCommand="Nav_OnClick" CommandName="Page" />
            <asp:LinkButton ID="lnkbtn5" CssClass="page-numbers" runat="server" onCommand="Nav_OnClick" CommandName="Page" />
            <asp:LinkButton ID="lnkbtn6" CssClass="page-numbers" runat="server" onCommand="Nav_OnClick" CommandName="Page" />
            <asp:LinkButton ID="lnkbtn7" CssClass="page-numbers" runat="server" onCommand="Nav_OnClick" CommandName="Page" />
            <asp:LinkButton ID="lnkbtn8" CssClass="page-numbers" runat="server" onCommand="Nav_OnClick" CommandName="Page" />
            <asp:LinkButton ID="lnkbtn9" CssClass="page-numbers" runat="server" onCommand="Nav_OnClick" CommandName="Page" />
            <asp:LinkButton id="btnNext" runat="server" Text=" Next " CssClass="page-numbers next" onCommand="Nav_OnClick" CommandName="Next" />
            <asp:LinkButton id="btnLast" runat="server" Text=" Last " CssClass="page-numbers prev" onCommand="Nav_OnClick" CommandName="Last"  />
            <asp:HiddenField ID="HfFirst" runat="server" />
            <asp:HiddenField ID="HfLast" runat="server" />

In aspx.cs page:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            BindData(); //By default your grid section will be disabled.
        }
    }
    protected void BindData()
    {
        //Write your code for Button click
        getData(gridPageSize, 1); //Default first page will be binded to grid.
    }
    protected void Nav_OnClick(object sender, CommandEventArgs e)
    {

        int _currentPageNumber = 1;
        switch (e.CommandName)
        {
            case "First":
                _currentPageNumber = 1;
                break;
            case "Prev":
                _currentPageNumber = Int32.Parse(lblCurrentPage.Text) - 1;
                break;
            case "Page":
                LinkButton lnkbutton = (LinkButton)sender;
                _currentPageNumber = Int32.Parse(lnkbutton.Text);
                break;
            case "Next":
                _currentPageNumber = Int32.Parse(lblCurrentPage.Text) + 1;
                break;
            case "Last":
                _currentPageNumber = Int32.Parse(HfLast.Value);
                break;
        }
        getData(gridPageSize, _currentPageNumber);

    }
    private void getData(int pageSize, int pageIndex)
    {
        try
        {
            string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["database"].ConnectionString;

            //Prepare Sql connection
            SqlConnection con = new SqlConnection(connectString);
            con.Open();

            //Prepare Sql Command
            SqlCommand cmd = new SqlCommand("dbo.GetProducts", con);
            cmd.CommandType = CommandType.StoredProcedure;


            SqlParameter sqlPar2 = cmd.Parameters.Add("@CurrentPage", SqlDbType.Int);
            sqlPar2.Value = pageIndex;

            SqlParameter sqlPar3 = cmd.Parameters.Add("@PageSize", SqlDbType.Int);
            sqlPar3.Value = pageSize;

            //Use Data Adapter to get results
            SqlDataAdapter da = new SqlDataAdapter(cmd);

            DataSet ds = new DataSet();
            da.Fill(ds);

            if (ds.Tables[0].Rows.Count > 0)
                //DataToGrid(ds, pageIndex);
                Pagination.DataToGrid(GridView1, ds, pageIndex, lblCurrentPage, btnPrev, btnNext,btnFirst,btnLast,HfLast);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }


Pagination Class:

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

/// <summary>
/// Summary description for BaseClass
/// </summary>
public class Pagination : System.Web.UI.Page
{
    public static int startPage = 1; //For Custom grid Index
    public static int endPage = 11; //For custom Grid Index
    public static int gridPageSize = 2; //Number of grid records
    public void DataToGrid(GridView gridView1, DataSet ds, int currentPage, HtmlGenericControl displayResults, Label lblCurrentPage, LinkButton btnPrev, LinkButton btnNext, LinkButton btnFirst,LinkButton btnLast, HiddenField HfLast)
    {
        gridView1.DataSource = ds.Tables[0];
        gridView1.DataBind();

        int totalCount = Convert.ToInt32(ds.Tables[1].Rows[0]["TotalCount"].ToString());
        HfLast.Value = ds.Tables[2].Rows[0].ItemArray[0].ToString();
        changeControlsText(totalCount, currentPage, gridPageSize, lblCurrentPage, btnPrev, btnNext, btnFirst, btnLast);
        displayResults.Style.Add("Display", "inline");
    }
    public void changeControlsText(int totalCount, int currentPage, int gridPageSize, Label lblCurrentPage, LinkButton btnPrev, LinkButton btnNext, LinkButton btnFirst, LinkButton btnLast)
    {
        int remainder = 0;
        int totalPages = 0;
        Math.DivRem(totalCount, gridPageSize, out remainder);
        if (remainder == 0)
            totalPages = totalCount / gridPageSize;
        else
            totalPages = (totalCount / gridPageSize) + 1;

        //Using the total count & gridPage size we have found out the total number of pages

        lblCurrentPage.Text = currentPage.ToString();
        //This label is hidden label, which will be having the current page user is looking at.

        EnableLinkButtons(currentPage, totalPages,btnPrev,btnNext,btnFirst,btnLast);
        //Call this function to Enable or disable appropriate Link Buttons.
    }
    public void EnableLinkButtons(int currentPage, int totalPages, LinkButton btnPrev, LinkButton btnNext, LinkButton btnFirst, LinkButton btnLast)
    {
        //If we got only one page, then disable previous & next button.
        if (totalPages == 1)
        {
            btnPrev.Enabled = false;
            btnNext.Enabled = false;
            btnFirst.Enabled = false;
            btnLast.Enabled = false;
        }
        else
        {
            //we got more than one page, then how the button should show?
            if (currentPage == 1) //if the current page is '1' then Previous button is disable & Next button is enabled.
            {
                btnPrev.Enabled = false;
                btnNext.Enabled = true;
                btnFirst.Enabled = false;
                btnLast.Enabled = true;
            }
            else if (currentPage == totalPages) //If we are on the last page then disable Next button and enable Prev button.
            {
                btnPrev.Enabled = true;
                btnNext.Enabled = false;
                btnFirst.Enabled = true;
                btnLast.Enabled = false;
            }
            else //Neither of the above then enable both Prev and Next buttons.
            {
                btnPrev.Enabled = true;
                btnNext.Enabled = true;
                btnFirst.Enabled = true;
                btnLast.Enabled = true;
            }
        }
        //Now we are done with Next & prev buttons, now render our pager buttons.

        //Set the startpage of indexer
        if (currentPage > endPage - 1) //If user click on last button of your page indexer Then what show we do?
        {
            if (totalPages - currentPage < 4) //here 4 is total buttons/2 ( middle)
            {
                startPage = totalPages - 9; // instead of 8 you can customize on your own.
            }
            else
                startPage = currentPage - 4; //4 is middle number
        }
        else if (currentPage < startPage + 1)//What if user clicks on first button of page indexer?
        {
            startPage = currentPage - 4;
        }

        if (startPage < 1) //if some how the logic above goes to negative then make sure your start page is always 1.
            startPage = 1;

        string controlID = "";
        int value;
        for (int i = 0; i < 10; i++)
        {
            controlID = "lnkbtn" + i.ToString();//Get your link button id.
            value = startPage + i;//Assign a value to it.
            if (value <= totalPages) //so Enable all the pages till you meet cross 8 or you reached max pages.
            {
                makeVisibleButtons(controlID, value.ToString(), currentPage, true);
                endPage = value;
            }
            else
                makeVisibleButtons(controlID, value.ToString(), currentPage, false);
        }
    }
    public void makeVisibleButtons(string ControlID, string value, int currentPage, bool vsble)
    {
        LinkButton linkBtn = (LinkButton)FindControl(ControlID);
        linkBtn.Visible = vsble;
        linkBtn.Text = value;
        if (currentPage == Int32.Parse(value))
        {
            linkBtn.CssClass = "page-numbers current";
        }
        else
        {
            linkBtn.CssClass = "page-numbers";
        }
    }
}


CSS for Pagination:
.pager {
margin-bottom:10px;
margin-top:10px;
}
.page-numbers {
border:1px solid #CCCCCC;
color:#808185;
display:block;
float:left;
font-family:Trebuchet MS,Helvetica,sans-serif;
font-size:130%;
margin-right:3px;
padding:4px 4px 3px;
text-decoration:none;
}
.page-numbers.desc {
border:medium none;
}
.page-numbers:hover {
text-decoration:none;
}
.page-numbers.next, .page-numbers.prev {
border:1px solid #FFFFFF;
}
.page-numbers.current {
background-color:#808185;
border:1px solid #808185;
color:#FFFFFF;
font-weight:bold;
}
.page-numbers.dots {
border:1px solid #FFFFFF;
}

Stored procedure:

CREATE PROCEDURE GetProducts
(
@CurrentPage INT,
@PageSize INT
)
AS

    SELECT ROW_NUMBER() OVER (ORDER BY [Name]) AS Row,ProductId,[Name],[Description],Price FROM  
     (
     SELECT
      ROW_NUMBER() OVER (ORDER BY [Name]) AS Row,
      ProductId,
      [Name],
      [Description],
      Price
     FROM Product
     ) AS ProductWithRowNumbers
    WHERE  Row >= (@CurrentPage - 1) * @PageSize + 1 AND Row <= @CurrentPage*@PageSize

    SELECT COUNT(*) as TotalCount FROM Product
  
    SELECT  CEILING(COUNT(*) / CAST(@PageSize AS FLOAT)) NumberOfPages
     FROM  Product



SELECT ROW_NUMBER() OVER (ORDER BY Emp_Id) AS Row,Emp_Id,Emp_Name,[Address],Desig_Name,SalaryBasis,FixedSalary FROM  
     (
     SELECT
      ROW_NUMBER() OVER (ORDER BY Emp_Id) AS Row,Emp_Id,Emp_Name,[Address],Desig_Name,SalaryBasis,FixedSalary
       FROM Employee_View
     ) AS EmpWitRowNos
    WHERE  Row >= (@CurrentPage - 1) * @PageSize + 1 AND Row <= @CurrentPage*@PageSize

    SELECT COUNT(*) as TotalCount FROM Employee_View
  
    SELECT  CEILING(COUNT(*) / CAST(@PageSize AS FLOAT)) NumberOfPages
     FROM  Employee_View



Try this for custom pagination in gridview....

1 comment:

  1. Thanks to you share with me this awesome information.Keep it up...

    ReplyDelete