ASP.NET DataGrid - Custom Paging using the Cache Object - Part II

This article is in continuation with the previous article on implementing Custom Paging for ASP.NET DataGrid using the Cache object.

In case you have missed out the previous article, please check Part I

Just to recall, we declared a DataGrid with AllowPaging="true" and set the PagerStyle-Visible="false". Also, we declared a Panel with LinkButtons for First, Previous, Next and Last links for Paging and set a Command event for the link buttons "NavigationLink_Click()".

We will examine the code for implementing paging.

Global Variables used for Paging

private int TotalPages;
private int TotalRecords;
private int CurrentPage;
private int PageSize;


Code for binding the Data to the DataGrid

private void BindData()
{
SqlConnection objCon = new SqlConnection("your connection string goes here");
SqlCommand objCmd = new SqlCommand("select * from customers", objCon);
DataSet dsNew = new DataSet();
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = objCmd;
da.Fill(ds);
Cache["AllRecords"] = ds;
dsNew = (DataSet)Cache["AllRecords"];
ViewState["TotalRecords"] = dsNew.Tables[0].Rows.Count;
DataGrid1.CurrentPageIndex = 0;
DataGrid1.DataSource = dsNew;
DataGrid1.DataBind();
TotalRecords = (int)ViewState["TotalRecords"];
ViewState["TotalPages"] = DataGrid1.PageCount;
ViewState["CurrentPage"] = 0;
PreviousPage.Enabled = false;
NextPage.Enabled = true;
FirstPage.Enabled = false;
LastPage.Enabled = true;
if(TotalRecords == 0)
{
DataGrid1.Visible = false;
Panel1.Visible = false;
}
else if(TotalRecords <= DataGrid1.PageSize) { DataGrid1.Visible = true; Panel1.Visible = true; lblPageDetails.Text = "1 - "+ TotalRecords.ToString() + " of " + TotalRecords.ToString(); NextPage.Enabled = false; LastPage.Enabled = false; } else { DataGrid1.Visible = true; Panel1.Visible = true; lblPageDetails.Text = "1 - "+ DataGrid1.PageSize.ToString() + " of " + TotalRecords.ToString(); } }


Code for the Pager link "NavigationLink_Click()"


protected void NavigationLink_Click (Object sender, CommandEventArgs e)
{
int RecordCount;
DataSet dSet = null;
dSet = (DataSet)Cache["AllRecords"];
PageSize = DataGrid1.PageSize;
switch ( e.CommandName )
{
case "First":
ViewState["CurrentPage"] = 0;
DataGrid1.CurrentPageIndex = 0;
DataGrid1.DataSource = dSet;
DataGrid1.DataBind();
PreviousPage.Enabled = false;
NextPage.Enabled = true;
FirstPage.Enabled = false;
LastPage.Enabled = true;
TotalRecords = (int)ViewState["TotalRecords"];
lblPageDetails.Text = "1 - "+ PageSize.ToString() + " of " + TotalRecords.ToString();
break;
case "Last":
TotalPages = (int) ViewState["TotalPages"] ;
ViewState["CurrentPage"] = TotalPages - 1;
DataGrid1.CurrentPageIndex = TotalPages - 1 ; //since page number starts from 0
DataGrid1.DataSource = dSet;
DataGrid1.DataBind();
NextPage.Enabled = false;
PreviousPage.Enabled = true;
LastPage.Enabled = false;
FirstPage.Enabled = true;
RecordCount = (TotalPages - 1)* PageSize;
TotalRecords = (int)ViewState["TotalRecords"];
lblPageDetails.Text = (RecordCount+1).ToString()+" - "+ TotalRecords.ToString() + " of " + TotalRecords.ToString();
break;
case "Next":
CurrentPage =(int) ViewState["CurrentPage"];
CurrentPage = CurrentPage + 1;
ViewState["CurrentPage"] = CurrentPage;
DataGrid1.CurrentPageIndex = CurrentPage;
DataGrid1.DataSource = dSet;
DataGrid1.DataBind();
RecordCount = CurrentPage * PageSize;
TotalRecords = (int)ViewState["TotalRecords"];
if(CurrentPage == DataGrid1.PageCount-1)
{
NextPage.Enabled = false;
PreviousPage.Enabled = true;
LastPage.Enabled = false;
FirstPage.Enabled = true;
lblPageDetails.Text = (RecordCount+1).ToString()+" - "+ TotalRecords.ToString() + " of " + TotalRecords.ToString();
}
else
{
NextPage.Enabled = true;
PreviousPage.Enabled = true;
LastPage.Enabled = true;
FirstPage.Enabled = true;
lblPageDetails.Text = (RecordCount+1).ToString()+" - "+ (RecordCount+PageSize).ToString() + " of " + TotalRecords.ToString();
}
break;
case "Prev":
CurrentPage =(int) ViewState["CurrentPage"];
CurrentPage = CurrentPage - 1;
ViewState["CurrentPage"] = CurrentPage;
DataGrid1.CurrentPageIndex = CurrentPage;
DataGrid1.DataSource = dSet;
DataGrid1.DataBind();
RecordCount = CurrentPage * PageSize;
TotalRecords = (int)ViewState["TotalRecords"];
if(CurrentPage == 0)
{
PreviousPage.Enabled = false;
NextPage.Enabled = true;
FirstPage.Enabled = false;
LastPage.Enabled = true;
lblPageDetails.Text = "1 - "+ PageSize.ToString() + " of " +TotalRecords.ToString();
}
else
{
NextPage.Enabled = true;
PreviousPage.Enabled = true;
LastPage.Enabled = true;
FirstPage.Enabled = true;
lblPageDetails.Text = (RecordCount+1).ToString()+" - "+ (RecordCount+PageSize).ToString() + " of " + TotalRecords.ToString();
}
break;
}
}


Calling the DataGrid Binding method in the Page_Load Event


private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
BindData();
}
}


We will examine the code step-by-step:-

1. Declaring Global variables
We have declared certain global variables such that they are useful across the methods.

2. Binding the Data to the DataGrid
The first seven lines of code must be a familiar one for whoever creates a connection object, dataadapter and a dataset. We have used a sample "Customer" Table for this sample.

What is changed is that, we dont directly bind the DataGrid with the DataSet. Instead, we store the DataSet into the Cache object. The reason is that, the Cache object is going to store all the records that we retrieve from the Database in one shot and then remain useful in moving next,previous link buttons in the paging.

We then typecast the ViewState data into a new DataSet which is used to bind the DataGrid.

We then store the total number of records into ViewState. This is useful in showing the total records in the Pager Panel.

Then, we assign the current page index to 0 so that the DataGrid's first page is shown when the control generates for the first time.

The DataGrid is then bound to the New DataSet.

Then, the TotalPages the DataGrid requies to show all the records is set to ViewState and also the CurrentPageIndex is set to ViewState.

We then do various checkings to show, enable and disable the pager links based on the number of records etc., which is self-explanatory.

3. The Navigation_Link Method Code
The first thing we do in this method is to get the items from the Cache. Remember, this event is going to fire for any of the pager links clicked.

We then do a switch based on the CommandName argument that is passed and do relevant calculations to show respective count on the Pager links.

4. Page_Load Event
In the Page_Load event, the DataGrid binding method is called within the PostBack Condition check.

As you are aware, there are various calculations done based on the Link clicked such that it shows, the relevant items in the format "1-5 of 10", "6-10 of 10" etc., and also there is a First and Last link which can take you to the first page and last page of the records.

This also improves the performance since the bulk of records is stored in the Cache object and thereafter, there is no Database call unlike the traditional built-in paging functionality. This also accounts to quicker response.

You can also notice that the format of the Pager (text) is now in our control we can configure the Text as per our requirement unlike the limited options in the built-in paging mechanism.

This concludes the 2 part article series on implementing Custom Paging using the Cache object for ASP.NET DataGrid.

Cheers and Happy Programming !!!

ASP.NET DataGrid - Custom Paging using the Cache Object - Part I

ASP.NET DataGrid is one of the coolest controls (well its quite late now to remark, but I cannot stop from starting like this) that has been used by almost everyone who does coding in ASP.NET. Though there are other controls like Repeater, DataList, the popularity DataGrid has got among developers is enviable.

One of the primary concerns when using DataGrid web server control is the Paging functionality. In real world scenario you will always end up with huge data that cannot be showed once for all in a single page. The DataGrid needs to implement paging by which you show only limited number of records and provide navigation links for seeing the next set of records, previous records, etc., However, there are certain limitations in using the built-in paging functionality. They are


1. The Pager Style mode is limited to "Next Previous" or Numeric "1,2,.." etc., whereas in certain places we would like to have custom text which says 1-5 of 10 records, First page, Last Page in addition to the previous, next page etc.,

2. Everytime, the page link is clicked, the entire set of records is going to be retreived though only the actual number of items will be shown. Assume you have 10,000 records. Everytime the 10,000 records will be retrieved when you navigate between the pager links. This can be heavy over the network.

3. You need to bind the DataGrid everytime on the PageIndexChanged event.

While the above are certain performance overheads, still, for basic paging requirement, the built-in paging mechanism is more than enough. However, if you care for performance and want to implement your own way of efficient paging, DataGrid still offers you the way to do it. It welcomes you to implement custom paging for which you have to write the code. In built-in paging, it does the plumbing work internally whereas, in custom paging, you need to dirty your hands in code.

There are several ways in which you can implement custom paging. There have been wealth of articles on the same ever since ASP.NET 1.0 got released and I am sure there must be some articles already on the topic I am writing now. But this is just another approach to help people who want to implement custom paging and expand the possibilities with DataGrid.

Having said that, lets start our first step in implementing Custom Paging.

1. Declare the DataGrid with AllowPaging="true"

&lt;ASP:DATAGRID id="DataGrid1" Runat="server" AutoGenerateColumns="true" PageSize="5" AllowPaging="true" PagerStyle-Visible="False">
&lt;/ASP:DATAGRID>


If you notice in the above declaration, we have set AllowPaging="true" which is normal in any case where you implement paging. Secondly, we have set the PagerStyle-Visible="false" to ensure that DataGrid doesnt show up its default pager style "< >" since we have set the allowpaging to true.

2. The next step is declaring a Panel which contains the Pager links

&lt;asp:Panel id="Panel1" Runat="server" Visible="False">

&lt;TR>

&lt;TD id="LinkButtons" colSpan="2" runat="server">

&lt;ASP:LINKBUTTON id="FirstPage" Runat="server" text="First" OnCommand="NavigationLink_Click" CommandName="First">&lt;/ASP:LINKBUTTON>

&lt;ASP:LINKBUTTON id="PreviousPage" Runat="server" text="Previous" OnCommand="NavigationLink_Click" CommandName="Prev">&lt;/ASP:LINKBUTTON>

&lt;ASP:LABEL id="lblPageDetails" runat="Server" >&lt;/ASP:LABEL>

&lt;ASP:LINKBUTTON id="NextPage" Runat="server" text="Next" OnCommand="NavigationLink_Click" CommandName="Next">&lt;/ASP:LINKBUTTON>

&lt;ASP:LINKBUTTON id="LastPage" Runat="server" text="Last" OnCommand="NavigationLink_Click" CommandName="Last">&lt;/ASP:LINKBUTTON>

&lt;/TD>

&lt;/TR>

&lt;/asp:Panel>

In the above code you can notice that we have 4 linkbuttons one each for "First, Last, Previous, Next". All of them link to a single method "NavigationLink_Click", but pass different CommandNames such as "First", "Previous", "Next", "Last" to specify which button is clicked.

Also, we have a panel covering these link buttons. We will explore on how to implement the NavigationLink_Click method in the next part of this article.

Cheers and Happy Programming !!!

«December»
SunMonTueWedThuFriSat
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567