Click here to Skip to main content
15,867,568 members
Articles / Web Development / ASP.NET
Article

Custom paging for Gridview, DataGrid, DataList and Repeater Control in ASP.Net with C#

Rate me:
Please Sign up or sign in to vote.
3.86/5 (4 votes)
2 Jan 2009CPOL3 min read 75.4K   3.5K   46  
with the help of following code, you can ao=pply custom paing in

Introduction


This article comes with a solution for Custom paging in GridView Control in asp.net 2.0.However, Gridview supports inbuilt paging and requires almost no code to implement that, but the word "free" comes with some obvious restrictions. Most of the time, we have to go for Custom page for Gridview. Here i am trying to implement custom paging , which look something like following format :

"<< First < Previous 1 2 3 4 5 6 7 8 9 Next > Last >> "

Background

use of this article is very easy going and handy. you can also download the code (both aspx and .cs residing on different folders) and set Connectionstring as per your db instructs. as per the part of Database acting, it requires a single table, obviously, with some data.(just kidding...)

Using the code

So First thing "First". First a look at the aspx page design:

<form id="form1" runat="server">

<div>

<asp:GridView ID="GridView1" runat="server">

</asp:GridView>

<br />

<asp:Label ID="Label1" runat="server" Text=""></asp:Label>


<input type="hidden" value="6" id="PageSize" runat="server"/>

<input type="hidden" value="1" id="CurrentPage" runat="server"/>

<input type="hidden" id="TotalSize" runat="server"/>


<table align="right">

<tr>

<td>

<asp:LinkButton ID="first" runat="server" Text="<< First" OnClick="first_Click" 
                  CausesValidation="false" CssClass="blue_boldtext_link"></asp:LinkButton>

  

<asp:LinkButton ID="prev" runat="server" Text="< Previous" OnClick="prev_Click" 
                  CausesValidation="false" CssClass="blue_boldtext_link"></asp:LinkButton>

  

<asp:Label ID="lblPaging" runat="server"></asp:Label>

  

<asp:LinkButton ID="next" runat="server" Text="Next >" OnClick="next_Click" 
                 CausesValidation="false" CssClass="blue_boldtext_link"></asp:LinkButton>

   

<asp:LinkButton ID="last" runat="server" Text="Last >>" OnClick="last_Click" 
                 CausesValidation="false" CssClass="blue_boldtext_link"></asp:LinkButton>

</td>

</tr>

</table>

</div>

</form>

Then i have used three input type as:

1. PageSize = 6 (this is fix value, you can change it here and it depends how many records you want to display on a page at a time)

2. CurrentPage = 1 (initially set to 1 because you are viewing data from very first page. This is the most important because CurrentPage is the only vlaue wich is going to changed on every
condition depend where you clicked either on numeric or these link buttons.)

3. TotalSize = (this value is determined very first time at the method which is calling at page load. this simply tells you that how many total records are there in your table.)

i have used four linkbuttons named "<< First", "< Previous", "Next >", "Last >>" and set their
event handlers here. and also, a label control which is using to rendering dynamically created
numeric linkbuttons.

Now, check out for the Code page. Here i have used bind method more than 1 time just to bind data. means code is not fully optimized, but this thing is so because i want to keep things simpler so that people can understand easily and, once got it, modify according to their need.

/* declaration of public variables */

public static int countPerRenderPage = 0;
public static int countTotalRec = 0; 

binding gridview control with its associated data and basic binding control from aspx page:

void Page_Load(object sender, EventArgs e) 
{ if(!IsPostBack)
BindDataByChar("");
BindPaging();
}

bind method here:

public void rptBindGrid()

{

int count = 0;

string strCount = "select count(*) from ProductAttribute";

DataSet ds = new DataSet();

using (SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.
                  ConnectionStrings["attribiuteStr"].ConnectionString))

{

using (SqlCommand cmd = new SqlCommand(strCount, con))

{

con.Open();

TotalSize.Value = cmd.ExecuteScalar().ToString();

}

using (SqlDataAdapter da = new SqlDataAdapter("select * from ProductAttribute", con))

{

int StartRecord = (int.Parse(CurrentPage.Value) - 1) * (int.Parse(PageSize.Value));

da.Fill(ds, StartRecord, int.Parse(PageSize.Value), "ProductAttribute_k");


if ((count = ds.Tables[0].Rows.Count) > 0)

{

BuildPagers();

GridView1.DataSource = ds.Tables[0].DefaultView;

GridView1.DataBind();

}


}

}

}

Now, following function for numeric paging values such as 1,2,3,4... These values are dynamic in nature. Actually i have set to represent 6 records, so it will for records and on the bassis of total number of records, these numeric terms will be displayed. For example, if there are total 27 records, then 27/6= 4(+1)= 5(till 5as 1,2,3,4,5) will be shown.

private void BindPaging()

{

int i = 49;

if (countPerRenderPage != 0 && countTotalRec != 0)

{

int tillLoop = countTotalRec / countPerRenderPage;

for (int k = 0; k <= tillLoop; k++)

{

if (i < 58)

{

char c = (char)i;

LinkButton lnk = new LinkButton();

lnk.ID = "lnk" + c;

lnk.CausesValidation = false;

lnk.CssClass = "white12boldtxt";

lnk.Style["padding-right"] = "10px";

lnk.ForeColor = System.Drawing.Color.Red;

lnk.Text = c.ToString();

lnk.CommandArgument = c.ToString();

lnk.Command += new CommandEventHandler(Page_List_lnk);

lblPaging.Controls.Add(lnk);

i++; 

}

}

}

}

Now, in following function, binding data values on the bassis of numeric value selected. For simplicity, i have not merged logic in a single method. and implementthis for seperate methods:

void BindDataByChar(string alphabet)

{

int count = 0;

string strInput = string.Empty;

if(!String.IsNullOrEmpty(alphabet))

strInput = "select * from ProductAttribute where ProductAttribute like '" + alphabet + "%'";

else

strInput = "select * from ProductAttribute";

string strCount = "select count(*) from ProductAttribute";

DataSet ds = new DataSet();

using (SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager
                                     .ConnectionStrings["attribiuteStr"].ConnectionString))

{

using (SqlCommand cmd = new SqlCommand(strCount, con))

{

con.Open();

TotalSize.Value = cmd.ExecuteScalar().ToString();

countTotalRec = Convert.ToInt32(TotalSize.Value);

}

using (SqlDataAdapter da = new SqlDataAdapter(strInput, con))

{

int StartRecord = (int.Parse(CurrentPage.Value) - 1) * (int.Parse(PageSize.Value));

da.Fill(ds, StartRecord, int.Parse(PageSize.Value), "ProductAttribute_k");

if ((countPerRenderPage = count = ds.Tables[0].Rows.Count) > 0)

{

BuildPagers();

GridView1.DataSource = ds.Tables[0].DefaultView;

GridView1.DataBind();

}

}

}

}

This function set the visibility of "first", "Previous", "next" and "last" linkbuttons, depending upon the circumstance at which data you are getting at that particular time. For instance, you have got your table's last records by clicking numeric values; then at that time there is no logic of displaying "next" and "last" lnks on screen. hence i set their visible state false. Here is the Code:

private void BuildPagers()

{

if (((int.Parse(CurrentPage.Value)) - 1) > 0)

{

   prev.Visible = true;

 first.Visible = true;

 }

else

{

prev.Visible = false;

first.Visible = false;

}

if (int.Parse(CurrentPage.Value) * int.Parse(PageSize.Value) > int.Parse(TotalSize.Value))

{

next.Visible = false;

last.Visible = false;

}

else

{

   next.Visible = true;

   last.Visible = true;

}

}

Now, Link buttons event handlers here :

protected void next_Click(object sender, EventArgs e)

{

Page_List(sender, e);

}

protected void prev_Click(object sender, EventArgs e)

{

Page_List(sender, e);

}

protected void last_Click(object sender, EventArgs e)

{

Page_List(sender, e);

}

protected void first_Click(object sender, EventArgs e)

{

Page_List(sender, e);

}

find linkbutton by their Ids, and set CurrentPage values here.remember CurrentPage values initially set to 1. upon the cindition, we are also modifying CurrentPage values here.

public void Page_List(object sender, EventArgs e)

{

if (((LinkButton)sender).ID == "prev")

{

if (!String.IsNullOrEmpty(CurrentPage.Value))

{

if (((int.Parse(CurrentPage.Value)) - 1) > 0)

{

CurrentPage.Value = Convert.ToString(int.Parse(CurrentPage.Value) - 1);

}

}

}

else if (((LinkButton)sender).ID == "next")

{

if (!String.IsNullOrEmpty(CurrentPage.Value))

{

if (int.Parse(CurrentPage.Value) * int.Parse(PageSize.Value) < int.Parse(TotalSize.Value))

{

CurrentPage.Value = Convert.ToString(int.Parse(CurrentPage.Value) + 1);

}

}

}

else if (((LinkButton)sender).ID == "last")

{

if (!String.IsNullOrEmpty(CurrentPage.Value))

{

if (int.Parse(CurrentPage.Value) * int.Parse(PageSize.Value) < int.Parse(TotalSize.Value))

{

CurrentPage.Value = Convert.ToString((int.Parse(TotalSize.Value) / int.Parse(PageSize.Value)) + 1);

}

}

}

else if (((LinkButton)sender).ID == "first")

{

if (String.IsNullOrEmpty(CurrentPage.Value))

CurrentPage.Value = "1";

if (((int.Parse(CurrentPage.Value)) - 1) > 0)

CurrentPage.Value = "1";

}

// Now bind data 

rptBindGrid();

}

bind method for numeric values here:

public void rptBindGrid_k(string val)

{

CurrentPage.Value = val;

int StartRecord = 0;

int count = 0;

string strCount = "select count(*) from ProductAttribute";

DataSet ds = new DataSet();

using (SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager
                                  .ConnectionStrings["attribiuteStr"].ConnectionString))

{

using (SqlCommand cmd = new SqlCommand(strCount, con))

{

con.Open();

TotalSize.Value = cmd.ExecuteScalar().ToString();

}

using (SqlDataAdapter da = new SqlDataAdapter("select * from ProductAttribute", con))

{

if (!String.IsNullOrEmpty(CurrentPage.Value))

{

StartRecord = (int.Parse(CurrentPage.Value) - 1) * (int.Parse(PageSize.Value));

da.Fill(ds, StartRecord, int.Parse(PageSize.Value), "ProductAttribute_k");

}

else

{

StartRecord = 0;

da.Fill(ds, StartRecord, int.Parse(TotalSize.Value), "ProductAttribute_k");

}

if ((count = ds.Tables[0].Rows.Count) > 0)

{

if(StartRecord != 0)

BuildPagers();

GridView1.DataSource = ds.Tables[0].DefaultView;

GridView1.DataBind();

}

}

}

}

At last, the Event handler for dynamic displaying numeric values, while clicking it find their id values and then call method "rptBindGrid_k". because id values are set as 1,2,3,4... and once gettingg them, it is much easy to supply them as input for CurrentPage values.

public void Page_List_lnk(object sender, EventArgs e)

{

string[] charval = { "lnk" };

string[] strlId = (((LinkButton)sender).ID).Split(charval,StringSplitOptions.RemoveEmptyEntries);

string xfdsf = (((LinkButton)sender).ID).Remove(0, 3);

if (!String.IsNullOrEmpty(xfdsf))

rptBindGrid_k(xfdsf);

}

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
India India
The Author belonges to Almora, Uttarakhand, Northern part of India and one of the awesome and less explored. he was interested in microsoft technologies from his college days. he is also a regular contributor for http://forums.asp.net and many others. Currently associated with an reputed firm in India.

Comments and Discussions

 
-- There are no messages in this forum --