Scrollable
Datagrid with Paging
After reading the title of this article, the first question
that will come to your mind is. Why I need to enable
paging in a Datagrid if I have scrollbar in that Datagrid? User is anyway
going to scroll to see the data, so i can show all the data in one page
itself. This is what i also thought first, but in some cases you might require
to enable paging in scrollabe datagrid. For example, you might
avoid fetching all the rows at the same time for performance reason. In that
case, you need to have paging along with scrolling. So in this article
i am going to explain how you can create scrollable datagrid with paging.
This
article is continuation to my previous article
Scrollable DataGrid with Sorting. It
explains how you can have sorting in scrollable Datagrid. So i recommend reading that article,
before you start with this article.
Enabling
paging in datagrid is very simple, you just need to set AllowPaging,
AllowCustomPaging properties to true and set PageSize property based on your requirements. But if that DataGrid is scrollable,
then your paging row will appear at one end of the DataGrid. So if user wants
to move to next page, he has to scroll down to the last row and then click
next page link. Obviously this design is not user friendly. So better approach is
to have static paging table below the datagrid. This paging table will just
show the Paging elements. But to
hook the paging events of Datagrid to the static table, you need to do some
work.
First step
is to set the visible property of Pager section of Datagrid
to false. Here is the codesnippet of the aspx page,
<div style=" OVERFLOW: auto; WIDTH: 800px; HEIGHT: 152px">
<asp:DataGrid id="DataGrid1" runat="server"
AutoGenerateColumns="False" DataKeyField="CustomerID"
ShowHeader="true" AllowSorting="True" AllowPaging="True" PageSize="8"
PagerStyle-
Mode=NumericPages
PagerStyle-Visible=False >
<Columns>
<asp:templatecolumn headertext="Row Number"
ItemStyle-Width="200px">
<itemtemplate>
<%# (DataGrid1.PageSize*DataGrid1.CurrentPageIndex)+
Container.ItemIndex+1%>
</itemtemplate>
</asp:templatecolumn>
<asp:boundcolumn runat="server" DataField="CompanyName"
HeaderText="Company Name"
SortExpression="CompanyName"></asp:boundcolumn>
<asp:boundcolumn ItemStyle-Width="200px" runat="server"
DataField="ContactName"
HeaderText="Contact
Name"
SortExpression="ContactName"></asp:boundcolumn>
<asp:boundcolumn ItemStyle-Width="200px" runat="server"
DataField="Address"
HeaderText="Address"
SortExpression="Address"></asp:boundcolumn>
</Columns>
</asp:DataGrid>
</div>
<div style=" WIDTH: 800px; ">
<asp:table Runat="server" ID="PagerTable" name="PagerTable" Width="100%"
>
<asp:TableRow Runat="server" >
<asp:TableCell Runat=server ></asp:TableCell>
</asp:TableRow>
</asp:table>
</div>
If you check out this code, a table is there just below the datagrid to
show the paging elements. Next step is to create paging elements in this table
which is similar to datagrid paging elements. For that we need to handle
the item_created event and we need to have the following code in that event
handler.
Private
Sub DataGrid1_ItemCreated(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.DataGridItemEventArgs) Handles
DataGrid1.ItemCreated
If e.Item.ItemType = ListItemType.Pager Then
Dim i As Int16
PagerTable.Rows(0).Cells.Clear()
Dim oCell As New TableCell
oCell.ColumnSpan = 4
oCell.Width = New Unit(800, UnitType.Pixel)
oCell.HorizontalAlign = HorizontalAlign.Left
PagerTable.Rows(0).Cells.Add(oCell)
For i
= 0 To e.Item.Controls(0).Controls.Count - 1
If e.Item.Controls(0).HasControls Then
If e.Item.Controls(0).Controls(i).GetType.ToString =
"System.Web.UI.WebControls.DataGridLinkButton"
Then
Dim lbutton
As New LinkButton
Dim oControl As New LinkButton
oControl = CType(e.Item.Controls(0).Controls(i),
LinkButton)
lbutton.ID = oControl.ID
lbutton.Text = oControl.Text
lbutton.Attributes.Add("href",Page.GetPostBackClientHyperlink
(e.Item.Controls(0).Controls(i), ""))
PagerTable.Rows(0).Cells(0).Controls.Add(lbutton)
ElseIf
TypeOf e.Item.Controls(0).Controls(i) Is LiteralControl
Then
Dim oControl As New LiteralControl
Dim oControlTemp As New LiteralControl
oControl = e.Item.Controls(0).Controls(i)
oControlTemp.Text = oControl.Text
PagerTable.Rows(0).Cells(0).Controls.Add(oControlTemp)
ElseIf TypeOf e.Item.Controls(0).Controls(i) Is Label
Then
Dim oControl As New Label
Dim oControlTemp As New Label
oControl = e.Item.Controls(0).Controls(i)
oControlTemp.Text = oControl.Text
PagerTable.Rows(0).Cells(0).Controls.Add(oControlTemp)
End If
End If
Next
End If
Here what
we are doing is, we are checking whether created item is pager. If it is pager,
then get the controls inside pager and place it in pager
table. Since control inside Datagrid pager column is Datagridlinkbutton,
we cant place this control inside normal asp:table control. So we
need to create a linkbutton which is having same properties as this
datagridlinkbutton and place it in header table. Other than datagridlinkbutton
control, you will have literal and label control inside datagrid pager section,
which will also be copied to pager table. One more thing to check is, all the
paging elements in datagrid will be there only in first cell of datagrid pager
row. All the other columns in that row will be empty.
Now
you got all the paging elements in the pager table from datagrid pager row.
Next
step is to hook the event handler code for those paging elements. You cant do
this work in item_created event as paging event handler wont be available for those
datagrid pager items at this time in control life cycle. Also you can do this
in item_databound event as Item_databound event wont fire for Pager
Datagrid item. So best place to write this code is in Page_PreRender
event.
Private Sub
Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs)
Handles MyBase.PreRender
Dim Dgitem As DataGridItem
For Each Dgitem In DataGrid1.Controls(0).Controls
If Dgitem.ItemType = ListItemType.Pager Then
Dim i As Int16
For i = 0 To Dgitem.Controls(0).Controls.Count - 1
If Dgitem.Controls(0).HasControls Then
If
Dgitem.Controls(0).Controls(i).GetType.ToString =
"System.Web.UI.WebControls.DataGridLinkButton" Then
Dim lbutton As New LinkButton
Dim oControl As New LinkButton
oControl
= CType(Dgitem.Controls(0).Controls(i), LinkButton)
lbutton = PagerTable.Rows(0).Cells(0).Controls(i)
lbutton.Text = oControl.Text
lbutton.Attributes.Add("href",
Page.GetPostBackClientHyperlink(Dgitem.Controls(0).Controls(i),
""))
End If
End If
Next
End If
Next
End Sub
Now you have moved the
event handler code from paging elements of datagrid to the pager table. So when
you click any paging elements (like next page link) in pager table, it will
fire PageIndexChanged event of datagrid where you can write code to change the
current page of the Datagrid.
|