Introduction
I was creating a CMS system where I had to implement many pages using custom paging (huge data). Well, it is always frustrating writing the same code a million times, so I have created this paging control which can be reused all over a web-application or in multiple web sites.
Using the code
This control basically accepts the page size. You will have to customise this control according to the data control you are using. In this case, I am using a DataList
control.
public partial class PagingControl : System.Web.UI.UserControl
{
#region Declarations
private int _CurrentPage = 1;
private int _PageSize;
private int _TotalArticles;
private ArticleData _ArticleDate;
public delegate void _NextClick(Object sender,EventArgs e);
#endregion
#region Event Handlers
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["CurrentPage"] = CurrentPage;
}
else
{
CurrentPage = (int)ViewState["CurrentPage"];
}
lblTotal.Text = TotalPages.ToString();
lblCurrent.Text = CurrentPage.ToString();
UpdateButtons();
}
protected void btnPrevious_Click(object sender, EventArgs e)
{
CurrentPage -= 1;
ViewState["CurrentPage"] = CurrentPage;
lblCurrent.Text = CurrentPage.ToString();
UpdateButtons();
PopulateParentData();
}
protected void btnNext_Click(object sender, EventArgs e)
{
CurrentPage += 1;
ViewState["CurrentPage"] = CurrentPage;
lblCurrent.Text = CurrentPage.ToString();
UpdateButtons();
PopulateParentData();
}
#endregion
#region Public Properties
private int CurrentPage
{
get { return _CurrentPage; }
set { _CurrentPage = value; }
}
public int PageSize
{
get { return _PageSize; }
set { _PageSize = value; }
}
public DataTable ArticleTable
{
get
{
return ArticleData.GetArticleOnPaging(CurrentPage, PageSize);
}
}
public int TotalArticles
{
get
{
if (_TotalArticles == 0)
{
_TotalArticles = ArticleData.GetTotalArticles();
}
return _TotalArticles;
}
}
public int TotalPages
{
get
{
int totalPages;
double tPage = Math.Ceiling((double)TotalArticles / PageSize);
totalPages = int.Parse(tPage.ToString());
return totalPages;
}
}
#endregion
#region Private Property
private ArticleData ArticleData
{
get
{
if (_ArticleDate == null)
{
_ArticleDate = new ArticleData();
}
return _ArticleDate;
}
}
#endregion
#region Methods
private void UpdateButtons()
{
btnNext.Enabled = CurrentPage != TotalPages;
btnPrevious.Enabled = CurrentPage != 1;
}
private void PopulateParentData()
{
DataList dlArticles = (DataList)this.Parent.FindControl("dlArticles");
dlArticles.DataSource = ArticleTable;
dlArticles.DataBind();
}
#endregion
The DataList
will have following in the source view to pass the PageSize
to the DataGrid
:
<asp:DataList ID="dlArticles" runat="server" Width="723px">
<ItemTemplate>
<h2>---------------------------------------------------------</h2>
<table>
<tr>
<td> <asp:Label ID="Label2" runat ="server">
<%# DataBinder.Eval(Container.DataItem, "Heading") %>
</asp:Label>
</td>
</tr>
<tr>
<td>
<asp:Label ID="Label1" runat ="server">
<%# DataBinder.Eval(Container.DataItem, "Body") %>
</asp:Label>
</td>
</tr>
<tr>
<td>
<asp:Label ID="Label3" runat ="server">
<%# DataBinder.Eval(Container.DataItem, "InsertedDate")%>
</asp:Label>
</td>
</tr>
</table> </ItemTemplate> </asp:DataList></div>
<uc1:PagingControl ID="PagingControl1" runat="server" PageSize = "2"/>
And finally, the Stored Procedure which can do the custom paging for us:
CREATE PROCEDURE DBO.ArticleSelectOnPaging
(
@CurrentPage AS INT,
@PageSize AS INT
)
AS
DECLARE
@FromID AS INT,
@ToID AS INT
SET @FromID = ((@CurrentPage - 1) * @PageSize) + 1
SET @ToID = @CurrentPage * @PageSize
CREATE TABLE #TempTable
(
TempID INT IDENTITY PRIMARY KEY,
ArticleID INT,
Heading VARCHAR(50),
Body VARCHAR(50),
InsertedDate DATETIME
)
INSERT INTO #TempTable
(
ArticleID,
Heading,
Body,
InsertedDate
)
SELECT ArticleID,
Heading,
Body,
InsertedDate
FROM Article
SELECT ArticleID,
Heading,
Body,
CONVERT(VARCHAR(50),InsertedDate,103) AS InsertedDate FROM #TempTable
WHERE
TempID >= @FromID AND TempID <= @ToID