often a good idea to page the information if there is a lot of
it. For instance, if you have 10000 rows of information to
potentially display, it’s unreasonable to expect the user to wait to
download all of it at one time and scroll forever. It’s wasteful,
too. Instead, page it in smaller chunks (10-50). Then let
the user move to different pages of information. But when there
is a lot of pages, you don’t want the user to have to click multiple
times to get to page 15. If information is sorted, a user will
often know what page to jump to. In this
post, I’ll cover how to add a “jump-to-page” feature to the
paging mechanism of an ASP.NET DataGrid.
DataGrid. I’ve spoofed some data in the form of a string array,
and I have my basic, numeric pager:
<asp:DataGrid AllowPaging=”True” PagerStyle-Mode=”NumericPages”
PagerStyle-PageButtonCount=”10″ ID=”grid” Runat=”server” />
</form>
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public class WebForm1 : Page
{
protected DataGrid grid;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!IsPostBack)
{
grid.DataSource = this.GetSource();
this.BindGrid(0);
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
grid.PageIndexChanged += new DataGridPageChangedEventHandler(grid_PageIndexChanged);
}
private string[] GetSource()
{
//just imagine how you would get/cache your data source.
string[] rows = new string[10000];
for (int i = 0; i < 10000; i++)
{
rows[i] = i.ToString();
}
return rows;
}
private void BindGrid(int currentPageIndex)
{
grid.DataSource = this.GetSource();
grid.CurrentPageIndex = currentPageIndex;
grid.DataBind();
}
private void grid_PageIndexChanged(object source, DataGridPageChangedEventArgs e)
{
this.BindGrid(e.NewPageIndex);
}
}
This works fine, but I have to click so many times to get to page
100 (10 clicks). I would like to be able to punch in a number and
jump to that page quickly. Let’s examine the following code and
how I created some controls to insert into the DataGrid paging
mechanism. The DataGrid doesn’t provide a PageTemplate, so we
have to do a bit of manual control arrangement. First, we’ll set
up how we would like it to work:
Let’s add our jump-to section:
<form id=”Form1″ method=”post” runat=”server”>
<asp:DataGrid AllowPaging=”True” PagerStyle-Mode=”NumericPages”
PagerStyle-PageButtonCount=”10″ ID=”grid” Runat=”server” />
<asp:Panel ID=”pagerEnhancement” Runat=”server”>
Jump to page:
<asp:TextBox id=jumpToText Runat=”server” Width=”25″></asp:TextBox>
<asp:Button id=jumpToButton Runat=”server” Text=”Go”></asp:Button>
</asp:Panel>
</form>
Notice that we just have a textbox and a button. We’ve added code to make this affect the DataGrid page:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public class WebForm1 : Page
{
protected System.Web.UI.WebControls.TextBox jumpToText;
protected System.Web.UI.WebControls.Button jumpToButton;
protected System.Web.UI.WebControls.Panel pagerEnhancement;
protected DataGrid grid;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!IsPostBack)
{
grid.DataSource = this.GetSource();
this.BindGrid(0);
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
grid.PageIndexChanged += new DataGridPageChangedEventHandler(grid_PageIndexChanged);
jumpToButton.Click +=new EventHandler(jumpToButton_Click);
}
private string[] GetSource()
{
//just imagine how you would get/cache your data source.
string[] rows = new string[10000];
for (int i = 0; i < 10000; i++)
{
rows[i] = i.ToString();
}
return rows;
}
private void BindGrid(int currentPageIndex)
{
grid.DataSource = this.GetSource();
grid.CurrentPageIndex = currentPageIndex;
grid.DataBind();
}
private void grid_PageIndexChanged(object source, DataGridPageChangedEventArgs e)
{
this.BindGrid(e.NewPageIndex);
}
private void jumpToButton_Click(object sender, System.EventArgs e)
{
int newPage = int.Parse(jumpToText.Text);
this.BindGrid(newPage – 1); //The DataGrid needs a page index, zero-based.
}
}
This works, but when I make my DataGrid pretty, I don’t want this
paging attachment left out. I need it to be inside the DataGrid,
so let’s write some code to move it from outside the DataGrid to right
next to the default pager:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public class WebForm1 : Page
{
protected TextBox jumpToText;
protected Button jumpToButton;
protected Panel pagerEnhancement;
protected DataGrid grid;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!IsPostBack)
{
grid.DataSource = this.GetSource();
this.BindGrid(0);
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
grid.PageIndexChanged += new DataGridPageChangedEventHandler(grid_PageIndexChanged);
jumpToButton.Click += new EventHandler(jumpToButton_Click);
grid.ItemCreated +=new DataGridItemEventHandler(grid_ItemCreated);
}
private string[] GetSource()
{
//just imagine how you would get/cache your data source.
string[] rows = new string[10000];
for (int i = 0; i < 10000; i++)
{
rows[i] = i.ToString();
}
return rows;
}
private void BindGrid(int currentPageIndex)
{
grid.DataSource = this.GetSource();
grid.CurrentPageIndex = currentPageIndex;
grid.DataBind();
}
private void grid_PageIndexChanged(object source, DataGridPageChangedEventArgs e)
{
this.BindGrid(e.NewPageIndex);
}
private void jumpToButton_Click(object sender, EventArgs e)
{
int newPage = int.Parse(jumpToText.Text);
this.BindGrid(newPage – 1); //The DataGrid needs a page index, zero-based.
}
private void grid_ItemCreated(object sender, DataGridItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Pager)
{
TableCell pagerCell = (TableCell) e.Item.Controls[0];// User Trace to view the
//control tree and found out how to grab the pager.;
pagerCell.Controls.Add(pagerEnhancement);
}
}
}
Notice how I am listening to the ItemCreated event of the DataGrid
and then moving the control when I’m on the Pager. I used the
Trace feature to observe the DataGrid control to see how the Pager was
laid out. The DataGrid is rendered as an Html table, so I just
needed to move my extra paging controls to the appropriate TableCell.
Obviously, I have simplified this example to demonstrate the basics
of adding to the default paging mechanism in the DataGrid. When I
use this technique, I make the appearance a lot more attractive, and I
also validate that an actual page number was entered into the
TextBox. After all, I have to gracefully handle whatever the user
types into that box.