- It uses Link Buttons as suggested in http://stackoverflow.com/questions/14335067/passing-search-parameters-to-same-page-when-hyperlink-clicked https://stackoverflow.com/questions/14335067/passing-search-parameters-to-same-page-when-hyperlink-clicked
- The link buttons are added in Page_Load itself as listed in http://stackoverflow.com/questions/14364332/dynamic-controls-event-handlers-working https://stackoverflow.com/questions/14364332/dynamic-controls-event-handlers-working
- It is made as user control for reuse
- It uses Link Buttons as suggested in http://stackoverflow.com/questions/14335067/passing-search-parameters-to-same-page-when-hyperlink-clicked
- The link buttons are added in Page_Load itself as listed in http://stackoverflow.com/questions/14364332/dynamic-controls-event-handlers-working
- It is made as user control for reuse
- It uses Link Buttons as suggested in https://stackoverflow.com/questions/14335067/passing-search-parameters-to-same-page-when-hyperlink-clicked
- The link buttons are added in Page_Load itself as listed in https://stackoverflow.com/questions/14364332/dynamic-controls-event-handlers-working
- It is made as user control for reuse
Points of interest
- It uses Link Buttons as suggested in http://stackoverflow.com/questions/14335067/passing-search-parameters-to-same-page-when-hyperlink-clicked
- The link buttons are added in Page_Load itself as listed in http://stackoverflow.com/questions/14364332/dynamic-controls-event-handlers-working
- It is made as user control for reuse
QUESTIONS
Helper ClassUser Control Markup
namespace WebApplication1
{
public static class PagingHelper
{
public static PagingInfo GetPageHyperlinks(int totalRecordsInTable, int pageSize, int currentIndex, string requestUrl)
{
PagingInfo pagingInfo = new PagingInfo();
<%@ Control Language="C#" AutoEventWireup="true" pagingInfoCodeBehind="PagingUserControl.LinksToAdd = new Collection<HyperLink>();
string url = requestUrl;
int position = requestUrlascx.IndexOf('?');
if (position > 0)
{cs"
url = requestUrlInherits="PagingTestWebApplication.Substring(0, position);
}
if (totalRecordsInTable > 0)
{
int itemsBeforeCurrentPage = 4;
int itemsAfterCurrentPage = 2;
int itemsCountInMiddleSection = itemsBeforeCurrentPage + 1 + itemsAfterCurrentPage;
//string templates for links
string link = "<a href='" + url + "?Index=[Index]&Size=[Size]'><spanPagingUserControl" class='page-numbers'>##Text##</span></a>";%>
string link_pre = "<a href='" + url +<div "?Index=[Index]&Size=[Size]'><spanclass="pagingSection" class='page-numbersid="pagingSection" prev'>##Text##</span></a>";runat="server">
string link_next = "<a href='" + url<asp:LinkButton +ID="lnkPrevious" "?Index=[Index]&Size=[Size]'><spanrunat="server" class='pageCssClass='page-numbers next'>##Text##</span></a>";
Double numberOfPagesRequired = Convert.ToDouble(totalRecordsInTable / pageSize);
if (totalRecordsInTable % pageSize != 0)
{
numberOfPagesRequired = numberOfPagesRequired + 1;
}
prev' Visible="false" /OnClick="LinkButton_Click">Prev</Generate dynamic paging
int start;
if (currentIndex <= (itemsBeforeCurrentPage + 1))
{
start = 1;
}
else
{asp:LinkButton>
start<asp:LinkButton =ID="lnkFirst" currentIndexrunat="server" CssClass='page- itemsBeforeCurrentPage;
}
int lastAddedLinkIndex = 0;
int? firtsAddedLinkIndex = null;
for (int i = start; i < start + itemsCountInMiddleSection; i++)
{
if (i > numberOfPagesRequired)
{
//do not add more links if exceeded limit
continue;
}
//create dynamic HyperLinks
HyperLink lnk = new HyperLink();
lnk.ID = "lnk_" + i.ToString();
lnk.Text = i.ToString();
lnk.Text = i.ToString();
lastAddedLinkIndex = i;
if (firtsAddedLinkIndex == null)
{
firtsAddedLinkIndex = i;
numbers' }
Visible="false"
/OnClick="LinkButton_Click">1</Check whetehr current page
if (i == currentIndex)
{asp:LinkButton>
<asp:Label lnk.CssClassrunat="server" =ID="lblFirstDots" "pageCssClass="page-numbers current";
}
else
{
lnk.CssClass =prev" "page-numbers";Visible="false"
lnkText=".NavigateUrl = url + "?Index=" + i + "&Size=" + pageSize + "";
}
pagingInfo.LinksToAdd.Add(lnk);
}
if (numberOfPagesRequired > itemsCountInMiddleSection)
{
/"></Set dots (ellipse) visibility
pagingInfo.IsEndDotsVisible = lastAddedLinkIndex == numberOfPagesRequired ? false asp: true;Label>
pagingInfo.IsStartDotsVisible = firtsAddedLinkIndex <= 2 ? false <asp: true;
PlaceHolder ID="plhDynamicLink" /runat="server"></First and Last Page Links
pagingInfo.IsLastLinkVisible = lastAddedLinkIndex == numberOfPagesRequired ? false asp: true;PlaceHolder>
pagingInfo.IsFirstLinkVisible = firtsAddedLinkIndex == 1 ? false <asp: true;
pagingInfo.LastLinkTextLabel =runat="server" link.Replace("[Index]",ID="lblSecondDots" numberOfPagesRequired.ToString()).Replace("[Size]",Visible="false" pageSize.ToString()).Replace("##Text##",CssClass="page-numbers numberOfPagesRequired.ToString());prev"
pagingInfo.FirstLinkText = link.Replace("[Index]", (numberOfPagesRequired - numberOfPagesRequired + 1).ToString())Text=".Replace("[Size]", pageSize.ToString()).Replace("##Text##", (numberOfPagesRequired - numberOfPagesRequired + 1).ToString());
}
/"></For first page, there is no previous
if (currentIndex != 1)
{asp:Label>
pagingInfo.PreviousLinkText = link_pre.Replace("[Size]",<asp:LinkButton pageSize.ToString()).Replace("[Index]",ID="lnkLast" (currentIndexrunat="server" CssClass='page- 1).ToString()).Replace("##Text##", "Prev");
}
else
numbers' {Visible="false"
/OnClick="LinkButton_Click">Last</Hyperlink is replaced with textasp:LinkButton>
pagingInfo.PreviousLinkText<asp:LinkButton =ID="lnkNext" "<spanrunat="server" class='pageCssClass='page-numbers prev'>Prev</span>";
}
//For last page there is no Next
if (currentIndex != Convert.ToInt32(numberOfPagesRequired))
{
pagingInfo.NextLinkText = link_next.Replace("[Size]", pageSize.ToString()).Replace("[Index]", (currentIndex + 1).ToString()).Replace("##Text##", "Next");
}
else
{
next' Visible="false" /OnClick="LinkButton_Click">Next</Hyperlink is replaced with textasp:LinkButton>
pagingInfo.NextLinkText = "<span class='page-numbers next'>Next<</span>";
}
}
return pagingInfo;
}
}
}div>
Data Transfer ClassUser Control Code Behind
public partial class PagingInfoPagingUserControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public Collection<HyperLink>int LinksToAddPreviousIndex { get; set; }
public bool?int IsEndDotsVisibleCurrentClickedIndex { get; set; }
public bool?event IsStartDotsVisibleEventHandler PaginationLinkClicked;
protected void LinkButton_Click(object sender, EventArgs e)
{ get; set; //Assumption: Text of the LinkButton will be same as index
LinkButton clickedLinkButton = (LinkButton)sender;
if (String.Equals(clickedLinkButton.Text, "Next"))
{
//Next Page index will be one greater than current
//Note: If the current index is the last page, "Next" control will be in disabled state
CurrentClickedIndex = PreviousIndex + 1;
}
else if (String.Equals(clickedLinkButton.Text, "Prev"))
{
//Previous Page index will be one less than current
//Note: If the current index is the first page, "Prev" control will be in disabled state
CurrentClickedIndex = PreviousIndex - 1;
}
else
{
CurrentClickedIndex = Convert.ToInt32(clickedLinkButton.Text, CultureInfo.InvariantCulture);
}
//Raise event
if (this.PaginationLinkClicked != null)
{
this.PaginationLinkClicked(clickedLinkButton, e);
}
}
public bool?void IsFirstLinkVisiblePreAddAllLinks(int tableDataCount,int pageSize, int currentIndex)
{ get; set; if (tableDataCount > 0)
{
PagingInfo info = PagingHelper.GetAllLinks(tableDataCount, pageSize, currentIndex);
//Remove all controls from the placeholder
plhDynamicLink.Controls.Clear();
if (info.PaginationLinks != null)
{
foreach (LinkButton link in info.PaginationLinks)
{
//Adding Event handler must be done inside Page_Laod /Page_Init
link.Click += new EventHandler(LinkButton_Click);
//Validation controls should be executed before link click.
link.ValidationGroup = "Search";
this.plhDynamicLink.Controls.Add(link);
}
}
}
}
public boolvoid AddPageLinks(int tableDataCount, int pageSize, int index)
{
if (tableDataCount > 0)
{
pagingSection.Visible = true;
PagingInfo info = PagingHelper.GetPageLinks(tableDataCount, pageSize, index);
//Remove all controls from the placeholder
plhDynamicLink.Controls.Clear();
if (info.PaginationLinks != null)
{
lnkPrevious.Visible = info.PaginationLinks.Count > 0 ? true : false;
lnkNext.Visible = info.PaginationLinks.Count > 0 ? true : false;
foreach (LinkButton link in info.PaginationLinks)
{
//Validation controls should be executed before link click.
link.ValidationGroup = "Search";
this.plhDynamicLink.Controls.Add(link);
}
}
//Dots visiblity
if (info.IsEndDotsVisible != null)
{
lblSecondDots.Visible = Convert.ToBoolean(info.IsEndDotsVisible, CultureInfo.InvariantCulture);
}
else
{
lblSecondDots.Visible = false;
}
if (info.IsStartDotsVisible != null)
{
lblFirstDots.Visible = Convert.ToBoolean(info.IsStartDotsVisible, CultureInfo.InvariantCulture);
}
else
{
lblFirstDots.Visible = false;
}
//First and Last Links
if (info.IsFirstLinkVisible != null)
{
lnkFirst.Visible = Convert.ToBoolean(info.IsFirstLinkVisible, CultureInfo.InvariantCulture);
}
else
{
lnkFirst.Visible = false;
}
if (info.IsLastLinkVisible != null)
{ get; set; lnkLast.Visible = Convert.ToBoolean(info.IsLastLinkVisible, CultureInfo.InvariantCulture);
lnkLast.Text = info.NumberOfPagesRequired.ToString(CultureInfo.InvariantCulture);
}
public string FirstLinkText else
{ get; set; lnkLast.Visible = false;
}
public string LastLinkText //For first page, there is no previous
if (index != 1 && info.NumberOfPagesRequired != 1)
{ get; set; lnkPrevious.Enabled = true;
}
public string PreviousLinkText else
{ get; set; lnkPrevious.Enabled = false;
}
public string NextLinkText //For last page there is no Next
if (index != info.NumberOfPagesRequired && info.NumberOfPagesRequired != 1)
{ get; set; lnkNext.Enabled = true;
}
else
{
lnkNext.Enabled = false;
}
}
else
{
pagingSection.Visible = false;
}
}
}
Code Behind DTO
namespace WebApplication1
{
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
int size = 0; int index = 0;
if (!Page.IsPostBack)
{
string test = this.Page.Request.Url.ToString();
string sizeTest = Request["Size"];
string indexTest = Request["Index"];
size = string.IsNullOrEmpty(Request["Size"]) ? 5 : Convert.ToInt32(Request["Size"]);
index = string.IsNullOrEmpty(Request["Index"]) ? 1 : Convert.ToInt32(Request["Index"]);
//load data from database
BindGrid(size, index);
}
}
void BindGrid(int pageSize, int index)
{
try
{
string ConnStr = "Data Source=.;Initial Catalog=LibraryReservationSystem;Integrated Security=True;Connect Timeout=30";
//the sql query with paging logics
String SQL = @"select * from
(SELECT ROW_NUMBER() OVER (ORDER BY EmpID asc) as row,*
FROM Employee) tblTemp
WHERE row between (" + index + " - 1) * " + pageSize + " + 1 and " + index + "*" + pageSize + " ";
SQL += " select COUNT(*) from Employee";
//fetching data from database suing SqlDataAdapter Fill method to bind the Gridview
SqlDataAdapter ad = new SqlDataAdapter(SQL, ConnStr);
DataSet ds = new DataSet();
ad.Fill(ds);
this.gvPaging.DataSource = ds.Tables[0];
this.gvPaging.DataBind();
DataTable tableForData = ds.Tables[0];
DataTable tableForRowCount = ds.Tables[1];
int totalRecordsInTable = Convert.ToInt32(tableForRowCount.Rows[0][0]);
PagingInfo info = PagingHelper.GetPageHyperlinks(totalRecordsInTable, pageSize, index, this.Page.Request.Url.ToString());
if(info.LinksToAdd!=null)
{
foreach (HyperLink link in info.LinksToAdd)
public Collection<LinkButton> PaginationLinks {
this.pl.Controls.Add(link);
}
get; set; }
//Dots visiblity
public ifbool? (info.IsEndDotsVisible != null)
{
spDot2.Visible = Convert.ToBoolean(info.IsEndDotsVisible);
get; set; }
public ifbool? (info.IsStartDotsVisible != null)
{ spDot1.Visible = Convert.ToBoolean(info.IsStartDotsVisible);
get; set; }
//First and Last Links
public ifbool? (info.IsFirstLinkVisible != null)
{ lblIst.Visible = Convert.ToBoolean(info.IsFirstLinkVisible);
lblIst.Text = info.FirstLinkText;
get; set; }
public ifbool? (info.IsLastLinkVisible != null)
{ lblLast.Visible = Convert.ToBoolean(info.IsLastLinkVisible);
lblLast.Text = info.LastLinkText;
}
//Pre and Next
lblpre.Text = info.PreviousLinkText;
lblnext.Text = info.NextLinkText;
get; set; }
catch (Exception ee)
public int NumberOfPagesRequired { //catch the exception
}
get; set; }
}
}
Helper
public static class PagingHelper
{
public static PagingInfo GetAllLinks(int totalRecordsInTable, int pageSize, int previousIndex)
{
string LinkButtonIDPrefix = "lnK";
PagingInfo pagingInfo = new PagingInfo();
pagingInfo.PaginationLinks = new Collection<LinkButton>();
if (totalRecordsInTable > 0)
{
int itemsBeforePage = 4;
int itemsAfterPage = 2;
int dynamicDisplayCount = itemsBeforePage + 1 + itemsAfterPage;
Double numberOfPagesRequired = Convert.ToDouble(totalRecordsInTable / pageSize);
if (totalRecordsInTable % pageSize != 0)
{
numberOfPagesRequired = numberOfPagesRequired + 1;
}
if (numberOfPagesRequired == 0)
{
numberOfPagesRequired = 1;
}
//Note: This function adds only the probable Links that the user can click (based on previous click).
//This is needed sice dynamic controls need to be added while Page_Load itself for event handlers to work
//In case of any bug, easiest way is add all links from 1 to numberOfPagesRequired
//Following is an optimized way
int endOfLeftPart = dynamicDisplayCount;
//User may click "1". So the first 7 items may be required for display. Hence add them for event handler purpose
for (int i = 1; i <= endOfLeftPart; i++)
{
//Create dynamic Links
LinkButton lnk = new LinkButton();
lnk.ID = LinkButtonIDPrefix + i.ToString(CultureInfo.InvariantCulture);
lnk.Text = i.ToString(CultureInfo.InvariantCulture);
pagingInfo.PaginationLinks.Add(lnk);
}
int startOfRighPart = Convert.ToInt32(numberOfPagesRequired) - dynamicDisplayCount + 1;
//User may click the last link. So the last 7 items may be required for display. Hence add them for event handler purpose
for (int i = startOfRighPart; i <= Convert.ToInt32(numberOfPagesRequired); i++)
{
//Links already added should not be added again
if (i > endOfLeftPart)
{
//Create dynamic Links
LinkButton lnk = new LinkButton();
lnk.ID = LinkButtonIDPrefix + i.ToString(CultureInfo.InvariantCulture);
lnk.Text = i.ToString(CultureInfo.InvariantCulture);
pagingInfo.PaginationLinks.Add(lnk);
}
}
//User may click on 4 items before current index as well as 2 items after current index
for (int i = (previousIndex - itemsBeforePage); i <= (previousIndex + itemsAfterPage); i++)
{
//Links already added should not be added again
if (i > endOfLeftPart && i < startOfRighPart)
{
//Create dynamic Links
LinkButton lnk = new LinkButton();
lnk.ID = LinkButtonIDPrefix + i.ToString(CultureInfo.InvariantCulture);
lnk.Text = i.ToString(CultureInfo.InvariantCulture);
pagingInfo.PaginationLinks.Add(lnk);
}
}
}
return pagingInfo;
}
public static PagingInfo GetPageLinks(int totalRecordsInTable, int pageSize, int currentIndex)
{
string LinkButtonIDPrefix = "lnK";
PagingInfo pagingInfo = new PagingInfo();
pagingInfo.PaginationLinks = new Collection<LinkButton>();
if (totalRecordsInTable > 0)
{
int itemsBeforePage = 4;
int itemsAfterPage = 2;
int dynamicDisplayCount = itemsBeforePage + 1 + itemsAfterPage;
Double numberOfPagesRequired = Convert.ToDouble(totalRecordsInTable / pageSize);
if (totalRecordsInTable % pageSize != 0)
{
numberOfPagesRequired = numberOfPagesRequired + 1;
}
if (numberOfPagesRequired == 0)
{
numberOfPagesRequired = 1;
}
//Generate dynamic paging
int start;
if (currentIndex <= (itemsBeforePage + 1))
{
start = 1;
}
else
{
start = currentIndex - itemsBeforePage;
}
int lastAddedLinkIndex = 0;
int? firtsAddedLinkIndex = null;
for (int i = start; i < start + dynamicDisplayCount; i++)
{
if (i > numberOfPagesRequired)
{
break;
}
//Create dynamic Links
LinkButton lnk = new LinkButton();
lnk.ID = LinkButtonIDPrefix + i.ToString(CultureInfo.InvariantCulture);
lnk.Text = i.ToString(CultureInfo.InvariantCulture);
lastAddedLinkIndex = i;
if (firtsAddedLinkIndex == null)
{
firtsAddedLinkIndex = i;
}
//Check whetehr current page
if (i == currentIndex)
{
lnk.CssClass = "page-numbers current";
}
else
{
lnk.CssClass = "page-numbers";
}
pagingInfo.PaginationLinks.Add(lnk);
}
if (numberOfPagesRequired > dynamicDisplayCount)
{
//Set dots (ellipse) visibility
pagingInfo.IsEndDotsVisible = lastAddedLinkIndex == numberOfPagesRequired ? false : true;
pagingInfo.IsStartDotsVisible = firtsAddedLinkIndex <= 2 ? false : true;
//First and Last Page Links
pagingInfo.IsLastLinkVisible = lastAddedLinkIndex == numberOfPagesRequired ? false : true;
pagingInfo.IsFirstLinkVisible = firtsAddedLinkIndex == 1 ? false : true;
}
pagingInfo.NumberOfPagesRequired = Convert.ToInt32(numberOfPagesRequired);
}
return pagingInfo;
}
}
MARK UPASPX Page
<form<%@ runat="server">
<inputPage type="hidden"Language="C#" runat="server"AutoEventWireup="true" id="hdSize"CodeBehind="LijosTest.aspx.cs" />Inherits="PagingTestWebApplication.LijosTest" %>
<div>
<%@ <asp:GridViewRegister ID="gvPaging"TagPrefix="CP" runat="server"TagName="LijosPager" AutoGenerateColumns="false"Src="~/PagingUserControl.ascx" GridLines="None">%>
<Columns>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <asp"http:TemplateField>
<ItemTemplate>//www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<table>
<html <tr>xmlns="http://www.w3.org/1999/xhtml">
<td<head class="text">runat="server">
Emp ID:<title></title>
<style <type="text/td>css">
<td align="left" colspan="5">.page-numbers
<%# Eval("EmpID")%>{
border: 1px solid </td>#CCC;
<td align="left" colspan="4"color: class="text">#808185;
Namedisplay: </td>block;
float: left;
font-size: 9pt;
margin-right: <td>3px;
padding: 4px 4px 3px;
text-decoration: none;
}
<%# Eval("Name")%>
.page-numbers.current
{
background-color: #808185;
border: 1px solid </td>#808185;
color: white;
font-weight: </tr>bold;
}
.page-numbers.next, </table>.page-numbers.prev
{
border: 1px solid </ItemTemplate>white;
</aspfont-size:TemplateField>
12pt;
}
</Columns>style>
</asp:GridView>head>
<div class="fl"><body>
<asp:Label<form runat="server"id="form1" ID="lblpre"></asp:Label>runat="server">
<asp:Label runat="server"TextBox ID="lblIst"ID="txtEmpName" Visible="false"><runat="server"></asp:Label>TextBox>
<asp:Label runat="server"Button ID="spDot1"ID="btnSearch" CssClass="page-numbersrunat="server" prev"Text="Button" Visible="false"ValidationGroup="Search"
OnClick="btnSearch_Click" Text="..."></asp:Label>>
<asp:PlaceHolder ID="pl" runat="server"></asp:PlaceHolder><div>
<asp:Label runat="server" ID="spDot2" Visible="false"GridView CssClass="page-numbersID="grdEmployee" prev"runat="server">
Text="..."><</asp:Label>GridView>
</div>
<asp<CP:LabelLijosPager runat="server"ID="uclPager" ID="lblLast"runat="server" Visible="false"></asp:Label>>
<asp:LabelHiddenField runat="server"ID="hdnCurrentIndex" ID="lblnext"></asp:Label>
runat="server" Value="Blank Value" />
</div>form>
</div>body>
</form>html>
CSSASPX Code Behind
public partial class LijosTest : System.page-numbersWeb.UI.Page
{
private {int pageSize = 25;
private int pageIndex = 1;
border:protected 1pxvoid solidPage_Load(object #CCC;sender, EventArgs e)
{
color: #808185; //Register event handler for user control event
display:this.uclPager.PaginationLinkClicked block;+= new EventHandler(paginationLink_Click);
float:if left;(Page.IsPostBack)
font{
//During all postbacks -size: 9pt;Add the pagination links to the page
margin-right: 3px; int tableDataCount = DatabaseSimulator.GetEmployeesCount(txtEmpName.Text);
padding: 4px 4px 3px; string defaultInitialValueForHiddenControl = "Blank Value";
text-decoration: none; int indexFromPreviousDataRetrieval = 1;
if (!String.Equals(hdnCurrentIndex.Value, defaultInitialValueForHiddenControl))
{
indexFromPreviousDataRetrieval = Convert.ToInt32(hdnCurrentIndex.Value, CultureInfo.InvariantCulture);
}
//Set property of user control
uclPager.page-numbersPreviousIndex = indexFromPreviousDataRetrieval;
//Call method in user control
uclPager.currentPreAddAllLinks(tableDataCount, pageSize, indexFromPreviousDataRetrieval);
}
}
protected void btnSearch_Click(object sender, EventArgs e)
{
background-color://When #808185;Search is clicked, reset the index to 1 (first page)
border:pageIndex 1px= solid1;
#808185; BindBusinessProcessActivitiesData();
}
color:protected white;void paginationLink_Click(object sender, EventArgs e)
{
font-weight: bold; //When link is clicked, set the pageIndex from user control property
pageIndex = uclPager.CurrentClickedIndex;
BindBusinessProcessActivitiesData();
}
private void BindBusinessProcessActivitiesData()
{
string name = txtEmpName.page-numbersText;
List<Employee> searchResult = DatabaseSimulator.nextGetData(name, pageSize, pageIndex).pageToList();
grdEmployee.DataSource = searchResult;
grdEmployee.DataBind();
//Index
hdnCurrentIndex.Value = pageIndex.ToString(CultureInfo.InvariantCulture);
//Get total number of records
int tableDataCount = DatabaseSimulator.GetEmployeesCount(name);
uclPager.AddPageLinks(tableDataCount, pageSize, pageIndex);
}
}
Database Part
public static class DatabaseSimulator
{
public static IEnumerable<Employee> GetData(string name, int pageSize,int index)
{
IEnumerable<Employee> employeesSource = SearchEmployees(name);
int skipUpto = ((index-numbers1) * pageSize);
IEnumerable<Employee> searchResult = employeesSource.prevSkip(skipUpto).Take(pageSize);
return searchResult;
}
public static int GetEmployeesCount(string name)
{
border:List<Employee> 1pxemployees solid= white;GetEmployees();
fontint employeesCount = 0;
if (String.IsNullOrEmpty(name))
{
employeesCount = employees.Count;
}
else
{
List<Employee> selectedEmployees = employees.Where(r => r.Name == name).ToList();
employeesCount = selectedEmployees.Count;
}
return employeesCount;
}
private static IEnumerable<Employee> SearchEmployees(string name)
{
List<Employee> employees = GetEmployees();
if (String.IsNullOrEmpty(name))
{
return employees;
}
return employees.Where(r => r.Name == name);
}
private static List<Employee> GetEmployees()
{
List<Employee> employees = new List<Employee>();
for (int i = 1; i <= 400; i++)
{
Employee emp = new Employee();
emp.EmpID = i;
if (i % 2 == 0)
{
emp.Name = "Divisible by 2";
}
else if (i % 3 == 0)
{
emp.Name = "Divisible by 3";
}
else if (i % 5 == 0)
{
emp.Name = "Divisible by 5";
}
else if (i % 7 == 0)
{
emp.Name = "Divisible by 7";
}
else
{
emp.Name = "Other -size:- 12pt;"+ i.ToString();
}
employees.Add(emp);
}
return employees;
}
}
public class Employee
{
public int EmpID { get; set; }
public string Name { get; set; }
}
QUESTIONS
Helper Class
namespace WebApplication1
{
public static class PagingHelper
{
public static PagingInfo GetPageHyperlinks(int totalRecordsInTable, int pageSize, int currentIndex, string requestUrl)
{
PagingInfo pagingInfo = new PagingInfo();
pagingInfo.LinksToAdd = new Collection<HyperLink>();
string url = requestUrl;
int position = requestUrl.IndexOf('?');
if (position > 0)
{
url = requestUrl.Substring(0, position);
}
if (totalRecordsInTable > 0)
{
int itemsBeforeCurrentPage = 4;
int itemsAfterCurrentPage = 2;
int itemsCountInMiddleSection = itemsBeforeCurrentPage + 1 + itemsAfterCurrentPage;
//string templates for links
string link = "<a href='" + url + "?Index=[Index]&Size=[Size]'><span class='page-numbers'>##Text##</span></a>";
string link_pre = "<a href='" + url + "?Index=[Index]&Size=[Size]'><span class='page-numbers prev'>##Text##</span></a>";
string link_next = "<a href='" + url + "?Index=[Index]&Size=[Size]'><span class='page-numbers next'>##Text##</span></a>";
Double numberOfPagesRequired = Convert.ToDouble(totalRecordsInTable / pageSize);
if (totalRecordsInTable % pageSize != 0)
{
numberOfPagesRequired = numberOfPagesRequired + 1;
}
//Generate dynamic paging
int start;
if (currentIndex <= (itemsBeforeCurrentPage + 1))
{
start = 1;
}
else
{
start = currentIndex - itemsBeforeCurrentPage;
}
int lastAddedLinkIndex = 0;
int? firtsAddedLinkIndex = null;
for (int i = start; i < start + itemsCountInMiddleSection; i++)
{
if (i > numberOfPagesRequired)
{
//do not add more links if exceeded limit
continue;
}
//create dynamic HyperLinks
HyperLink lnk = new HyperLink();
lnk.ID = "lnk_" + i.ToString();
lnk.Text = i.ToString();
lnk.Text = i.ToString();
lastAddedLinkIndex = i;
if (firtsAddedLinkIndex == null)
{
firtsAddedLinkIndex = i;
}
//Check whetehr current page
if (i == currentIndex)
{
lnk.CssClass = "page-numbers current";
}
else
{
lnk.CssClass = "page-numbers";
lnk.NavigateUrl = url + "?Index=" + i + "&Size=" + pageSize + "";
}
pagingInfo.LinksToAdd.Add(lnk);
}
if (numberOfPagesRequired > itemsCountInMiddleSection)
{
//Set dots (ellipse) visibility
pagingInfo.IsEndDotsVisible = lastAddedLinkIndex == numberOfPagesRequired ? false : true;
pagingInfo.IsStartDotsVisible = firtsAddedLinkIndex <= 2 ? false : true;
//First and Last Page Links
pagingInfo.IsLastLinkVisible = lastAddedLinkIndex == numberOfPagesRequired ? false : true;
pagingInfo.IsFirstLinkVisible = firtsAddedLinkIndex == 1 ? false : true;
pagingInfo.LastLinkText = link.Replace("[Index]", numberOfPagesRequired.ToString()).Replace("[Size]", pageSize.ToString()).Replace("##Text##", numberOfPagesRequired.ToString());
pagingInfo.FirstLinkText = link.Replace("[Index]", (numberOfPagesRequired - numberOfPagesRequired + 1).ToString()).Replace("[Size]", pageSize.ToString()).Replace("##Text##", (numberOfPagesRequired - numberOfPagesRequired + 1).ToString());
}
//For first page, there is no previous
if (currentIndex != 1)
{
pagingInfo.PreviousLinkText = link_pre.Replace("[Size]", pageSize.ToString()).Replace("[Index]", (currentIndex - 1).ToString()).Replace("##Text##", "Prev");
}
else
{
//Hyperlink is replaced with text
pagingInfo.PreviousLinkText = "<span class='page-numbers prev'>Prev</span>";
}
//For last page there is no Next
if (currentIndex != Convert.ToInt32(numberOfPagesRequired))
{
pagingInfo.NextLinkText = link_next.Replace("[Size]", pageSize.ToString()).Replace("[Index]", (currentIndex + 1).ToString()).Replace("##Text##", "Next");
}
else
{
//Hyperlink is replaced with text
pagingInfo.NextLinkText = "<span class='page-numbers next'>Next</span>";
}
}
return pagingInfo;
}
}
}
Data Transfer Class
public class PagingInfo
{
public Collection<HyperLink> LinksToAdd { get; set; }
public bool? IsEndDotsVisible { get; set; }
public bool? IsStartDotsVisible { get; set; }
public bool? IsFirstLinkVisible { get; set; }
public bool? IsLastLinkVisible { get; set; }
public string FirstLinkText { get; set; }
public string LastLinkText { get; set; }
public string PreviousLinkText { get; set; }
public string NextLinkText { get; set; }
}
Code Behind
namespace WebApplication1
{
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
int size = 0; int index = 0;
if (!Page.IsPostBack)
{
string test = this.Page.Request.Url.ToString();
string sizeTest = Request["Size"];
string indexTest = Request["Index"];
size = string.IsNullOrEmpty(Request["Size"]) ? 5 : Convert.ToInt32(Request["Size"]);
index = string.IsNullOrEmpty(Request["Index"]) ? 1 : Convert.ToInt32(Request["Index"]);
//load data from database
BindGrid(size, index);
}
}
void BindGrid(int pageSize, int index)
{
try
{
string ConnStr = "Data Source=.;Initial Catalog=LibraryReservationSystem;Integrated Security=True;Connect Timeout=30";
//the sql query with paging logics
String SQL = @"select * from
(SELECT ROW_NUMBER() OVER (ORDER BY EmpID asc) as row,*
FROM Employee) tblTemp
WHERE row between (" + index + " - 1) * " + pageSize + " + 1 and " + index + "*" + pageSize + " ";
SQL += " select COUNT(*) from Employee";
//fetching data from database suing SqlDataAdapter Fill method to bind the Gridview
SqlDataAdapter ad = new SqlDataAdapter(SQL, ConnStr);
DataSet ds = new DataSet();
ad.Fill(ds);
this.gvPaging.DataSource = ds.Tables[0];
this.gvPaging.DataBind();
DataTable tableForData = ds.Tables[0];
DataTable tableForRowCount = ds.Tables[1];
int totalRecordsInTable = Convert.ToInt32(tableForRowCount.Rows[0][0]);
PagingInfo info = PagingHelper.GetPageHyperlinks(totalRecordsInTable, pageSize, index, this.Page.Request.Url.ToString());
if(info.LinksToAdd!=null)
{
foreach (HyperLink link in info.LinksToAdd)
{
this.pl.Controls.Add(link);
}
}
//Dots visiblity
if (info.IsEndDotsVisible != null)
{
spDot2.Visible = Convert.ToBoolean(info.IsEndDotsVisible);
}
if (info.IsStartDotsVisible != null)
{ spDot1.Visible = Convert.ToBoolean(info.IsStartDotsVisible);
}
//First and Last Links
if (info.IsFirstLinkVisible != null)
{ lblIst.Visible = Convert.ToBoolean(info.IsFirstLinkVisible);
lblIst.Text = info.FirstLinkText;
}
if (info.IsLastLinkVisible != null)
{ lblLast.Visible = Convert.ToBoolean(info.IsLastLinkVisible);
lblLast.Text = info.LastLinkText;
}
//Pre and Next
lblpre.Text = info.PreviousLinkText;
lblnext.Text = info.NextLinkText;
}
catch (Exception ee)
{ //catch the exception
}
}
}
}
MARK UP
<form runat="server">
<input type="hidden" runat="server" id="hdSize" />
<div>
<asp:GridView ID="gvPaging" runat="server" AutoGenerateColumns="false" GridLines="None">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<table>
<tr>
<td class="text">
Emp ID:
</td>
<td align="left" colspan="5">
<%# Eval("EmpID")%>
</td>
<td align="left" colspan="4" class="text">
Name: </td>
<td>
<%# Eval("Name")%>
</td>
</tr>
</table>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<div class="fl">
<asp:Label runat="server" ID="lblpre"></asp:Label>
<asp:Label runat="server" ID="lblIst" Visible="false"></asp:Label>
<asp:Label runat="server" ID="spDot1" CssClass="page-numbers prev" Visible="false"
Text="..."></asp:Label>
<asp:PlaceHolder ID="pl" runat="server"></asp:PlaceHolder>
<asp:Label runat="server" ID="spDot2" Visible="false" CssClass="page-numbers prev"
Text="..."></asp:Label>
<asp:Label runat="server" ID="lblLast" Visible="false"></asp:Label>
<asp:Label runat="server" ID="lblnext"></asp:Label>
</div>
</div>
</form>
CSS
.page-numbers
{
border: 1px solid #CCC;
color: #808185;
display: block;
float: left;
font-size: 9pt;
margin-right: 3px;
padding: 4px 4px 3px;
text-decoration: none;
}
.page-numbers.current
{
background-color: #808185;
border: 1px solid #808185;
color: white;
font-weight: bold;
}
.page-numbers.next, .page-numbers.prev
{
border: 1px solid white;
font-size: 12pt;
}
Points of interest
- It uses Link Buttons as suggested in http://stackoverflow.com/questions/14335067/passing-search-parameters-to-same-page-when-hyperlink-clicked
- The link buttons are added in Page_Load itself as listed in http://stackoverflow.com/questions/14364332/dynamic-controls-event-handlers-working
- It is made as user control for reuse
QUESTIONS
User Control Markup
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="PagingUserControl.ascx.cs"
Inherits="PagingTestWebApplication.PagingUserControl" %>
<div class="pagingSection" id="pagingSection" runat="server">
<asp:LinkButton ID="lnkPrevious" runat="server" CssClass='page-numbers prev' Visible="false" OnClick="LinkButton_Click">Prev</asp:LinkButton>
<asp:LinkButton ID="lnkFirst" runat="server" CssClass='page-numbers' Visible="false"
OnClick="LinkButton_Click">1</asp:LinkButton>
<asp:Label runat="server" ID="lblFirstDots" CssClass="page-numbers prev" Visible="false"
Text="..."></asp:Label>
<asp:PlaceHolder ID="plhDynamicLink" runat="server"></asp:PlaceHolder>
<asp:Label runat="server" ID="lblSecondDots" Visible="false" CssClass="page-numbers prev"
Text="..."></asp:Label>
<asp:LinkButton ID="lnkLast" runat="server" CssClass='page-numbers' Visible="false"
OnClick="LinkButton_Click">Last</asp:LinkButton>
<asp:LinkButton ID="lnkNext" runat="server" CssClass='page-numbers next' Visible="false" OnClick="LinkButton_Click">Next</asp:LinkButton>
</div>
User Control Code Behind
public partial class PagingUserControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public int PreviousIndex { get; set; }
public int CurrentClickedIndex { get; set; }
public event EventHandler PaginationLinkClicked;
protected void LinkButton_Click(object sender, EventArgs e)
{ //Assumption: Text of the LinkButton will be same as index
LinkButton clickedLinkButton = (LinkButton)sender;
if (String.Equals(clickedLinkButton.Text, "Next"))
{
//Next Page index will be one greater than current
//Note: If the current index is the last page, "Next" control will be in disabled state
CurrentClickedIndex = PreviousIndex + 1;
}
else if (String.Equals(clickedLinkButton.Text, "Prev"))
{
//Previous Page index will be one less than current
//Note: If the current index is the first page, "Prev" control will be in disabled state
CurrentClickedIndex = PreviousIndex - 1;
}
else
{
CurrentClickedIndex = Convert.ToInt32(clickedLinkButton.Text, CultureInfo.InvariantCulture);
}
//Raise event
if (this.PaginationLinkClicked != null)
{
this.PaginationLinkClicked(clickedLinkButton, e);
}
}
public void PreAddAllLinks(int tableDataCount,int pageSize, int currentIndex)
{ if (tableDataCount > 0)
{
PagingInfo info = PagingHelper.GetAllLinks(tableDataCount, pageSize, currentIndex);
//Remove all controls from the placeholder
plhDynamicLink.Controls.Clear();
if (info.PaginationLinks != null)
{
foreach (LinkButton link in info.PaginationLinks)
{
//Adding Event handler must be done inside Page_Laod /Page_Init
link.Click += new EventHandler(LinkButton_Click);
//Validation controls should be executed before link click.
link.ValidationGroup = "Search";
this.plhDynamicLink.Controls.Add(link);
}
}
}
}
public void AddPageLinks(int tableDataCount, int pageSize, int index)
{
if (tableDataCount > 0)
{
pagingSection.Visible = true;
PagingInfo info = PagingHelper.GetPageLinks(tableDataCount, pageSize, index);
//Remove all controls from the placeholder
plhDynamicLink.Controls.Clear();
if (info.PaginationLinks != null)
{
lnkPrevious.Visible = info.PaginationLinks.Count > 0 ? true : false;
lnkNext.Visible = info.PaginationLinks.Count > 0 ? true : false;
foreach (LinkButton link in info.PaginationLinks)
{
//Validation controls should be executed before link click.
link.ValidationGroup = "Search";
this.plhDynamicLink.Controls.Add(link);
}
}
//Dots visiblity
if (info.IsEndDotsVisible != null)
{
lblSecondDots.Visible = Convert.ToBoolean(info.IsEndDotsVisible, CultureInfo.InvariantCulture);
}
else
{
lblSecondDots.Visible = false;
}
if (info.IsStartDotsVisible != null)
{
lblFirstDots.Visible = Convert.ToBoolean(info.IsStartDotsVisible, CultureInfo.InvariantCulture);
}
else
{
lblFirstDots.Visible = false;
}
//First and Last Links
if (info.IsFirstLinkVisible != null)
{
lnkFirst.Visible = Convert.ToBoolean(info.IsFirstLinkVisible, CultureInfo.InvariantCulture);
}
else
{
lnkFirst.Visible = false;
}
if (info.IsLastLinkVisible != null)
{ lnkLast.Visible = Convert.ToBoolean(info.IsLastLinkVisible, CultureInfo.InvariantCulture);
lnkLast.Text = info.NumberOfPagesRequired.ToString(CultureInfo.InvariantCulture);
}
else
{ lnkLast.Visible = false;
}
//For first page, there is no previous
if (index != 1 && info.NumberOfPagesRequired != 1)
{ lnkPrevious.Enabled = true;
}
else
{ lnkPrevious.Enabled = false;
}
//For last page there is no Next
if (index != info.NumberOfPagesRequired && info.NumberOfPagesRequired != 1)
{ lnkNext.Enabled = true;
}
else
{
lnkNext.Enabled = false;
}
}
else
{
pagingSection.Visible = false;
}
}
}
DTO
public class PagingInfo
{
public Collection<LinkButton> PaginationLinks { get; set; }
public bool? IsEndDotsVisible { get; set; }
public bool? IsStartDotsVisible { get; set; }
public bool? IsFirstLinkVisible { get; set; }
public bool? IsLastLinkVisible { get; set; }
public int NumberOfPagesRequired { get; set; }
}
Helper
public static class PagingHelper
{
public static PagingInfo GetAllLinks(int totalRecordsInTable, int pageSize, int previousIndex)
{
string LinkButtonIDPrefix = "lnK";
PagingInfo pagingInfo = new PagingInfo();
pagingInfo.PaginationLinks = new Collection<LinkButton>();
if (totalRecordsInTable > 0)
{
int itemsBeforePage = 4;
int itemsAfterPage = 2;
int dynamicDisplayCount = itemsBeforePage + 1 + itemsAfterPage;
Double numberOfPagesRequired = Convert.ToDouble(totalRecordsInTable / pageSize);
if (totalRecordsInTable % pageSize != 0)
{
numberOfPagesRequired = numberOfPagesRequired + 1;
}
if (numberOfPagesRequired == 0)
{
numberOfPagesRequired = 1;
}
//Note: This function adds only the probable Links that the user can click (based on previous click).
//This is needed sice dynamic controls need to be added while Page_Load itself for event handlers to work
//In case of any bug, easiest way is add all links from 1 to numberOfPagesRequired
//Following is an optimized way
int endOfLeftPart = dynamicDisplayCount;
//User may click "1". So the first 7 items may be required for display. Hence add them for event handler purpose
for (int i = 1; i <= endOfLeftPart; i++)
{
//Create dynamic Links
LinkButton lnk = new LinkButton();
lnk.ID = LinkButtonIDPrefix + i.ToString(CultureInfo.InvariantCulture);
lnk.Text = i.ToString(CultureInfo.InvariantCulture);
pagingInfo.PaginationLinks.Add(lnk);
}
int startOfRighPart = Convert.ToInt32(numberOfPagesRequired) - dynamicDisplayCount + 1;
//User may click the last link. So the last 7 items may be required for display. Hence add them for event handler purpose
for (int i = startOfRighPart; i <= Convert.ToInt32(numberOfPagesRequired); i++)
{
//Links already added should not be added again
if (i > endOfLeftPart)
{
//Create dynamic Links
LinkButton lnk = new LinkButton();
lnk.ID = LinkButtonIDPrefix + i.ToString(CultureInfo.InvariantCulture);
lnk.Text = i.ToString(CultureInfo.InvariantCulture);
pagingInfo.PaginationLinks.Add(lnk);
}
}
//User may click on 4 items before current index as well as 2 items after current index
for (int i = (previousIndex - itemsBeforePage); i <= (previousIndex + itemsAfterPage); i++)
{
//Links already added should not be added again
if (i > endOfLeftPart && i < startOfRighPart)
{
//Create dynamic Links
LinkButton lnk = new LinkButton();
lnk.ID = LinkButtonIDPrefix + i.ToString(CultureInfo.InvariantCulture);
lnk.Text = i.ToString(CultureInfo.InvariantCulture);
pagingInfo.PaginationLinks.Add(lnk);
}
}
}
return pagingInfo;
}
public static PagingInfo GetPageLinks(int totalRecordsInTable, int pageSize, int currentIndex)
{
string LinkButtonIDPrefix = "lnK";
PagingInfo pagingInfo = new PagingInfo();
pagingInfo.PaginationLinks = new Collection<LinkButton>();
if (totalRecordsInTable > 0)
{
int itemsBeforePage = 4;
int itemsAfterPage = 2;
int dynamicDisplayCount = itemsBeforePage + 1 + itemsAfterPage;
Double numberOfPagesRequired = Convert.ToDouble(totalRecordsInTable / pageSize);
if (totalRecordsInTable % pageSize != 0)
{
numberOfPagesRequired = numberOfPagesRequired + 1;
}
if (numberOfPagesRequired == 0)
{
numberOfPagesRequired = 1;
}
//Generate dynamic paging
int start;
if (currentIndex <= (itemsBeforePage + 1))
{
start = 1;
}
else
{
start = currentIndex - itemsBeforePage;
}
int lastAddedLinkIndex = 0;
int? firtsAddedLinkIndex = null;
for (int i = start; i < start + dynamicDisplayCount; i++)
{
if (i > numberOfPagesRequired)
{
break;
}
//Create dynamic Links
LinkButton lnk = new LinkButton();
lnk.ID = LinkButtonIDPrefix + i.ToString(CultureInfo.InvariantCulture);
lnk.Text = i.ToString(CultureInfo.InvariantCulture);
lastAddedLinkIndex = i;
if (firtsAddedLinkIndex == null)
{
firtsAddedLinkIndex = i;
}
//Check whetehr current page
if (i == currentIndex)
{
lnk.CssClass = "page-numbers current";
}
else
{
lnk.CssClass = "page-numbers";
}
pagingInfo.PaginationLinks.Add(lnk);
}
if (numberOfPagesRequired > dynamicDisplayCount)
{
//Set dots (ellipse) visibility
pagingInfo.IsEndDotsVisible = lastAddedLinkIndex == numberOfPagesRequired ? false : true;
pagingInfo.IsStartDotsVisible = firtsAddedLinkIndex <= 2 ? false : true;
//First and Last Page Links
pagingInfo.IsLastLinkVisible = lastAddedLinkIndex == numberOfPagesRequired ? false : true;
pagingInfo.IsFirstLinkVisible = firtsAddedLinkIndex == 1 ? false : true;
}
pagingInfo.NumberOfPagesRequired = Convert.ToInt32(numberOfPagesRequired);
}
return pagingInfo;
}
}
ASPX Page
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="LijosTest.aspx.cs" Inherits="PagingTestWebApplication.LijosTest" %>
<%@ Register TagPrefix="CP" TagName="LijosPager" Src="~/PagingUserControl.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style type="text/css">
.page-numbers
{
border: 1px solid #CCC;
color: #808185;
display: block;
float: left;
font-size: 9pt;
margin-right: 3px;
padding: 4px 4px 3px;
text-decoration: none;
}
.page-numbers.current
{
background-color: #808185;
border: 1px solid #808185;
color: white;
font-weight: bold;
}
.page-numbers.next, .page-numbers.prev
{
border: 1px solid white;
font-size: 12pt;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<asp:TextBox ID="txtEmpName" runat="server"></asp:TextBox>
<asp:Button ID="btnSearch" runat="server" Text="Button" ValidationGroup="Search"
OnClick="btnSearch_Click" />
<div>
<asp:GridView ID="grdEmployee" runat="server">
</asp:GridView>
</div>
<CP:LijosPager ID="uclPager" runat="server" />
<asp:HiddenField ID="hdnCurrentIndex" runat="server" Value="Blank Value" />
</form>
</body>
</html>
ASPX Code Behind
public partial class LijosTest : System.Web.UI.Page
{
private int pageSize = 25;
private int pageIndex = 1;
protected void Page_Load(object sender, EventArgs e)
{
//Register event handler for user control event
this.uclPager.PaginationLinkClicked += new EventHandler(paginationLink_Click);
if (Page.IsPostBack)
{
//During all postbacks - Add the pagination links to the page
int tableDataCount = DatabaseSimulator.GetEmployeesCount(txtEmpName.Text);
string defaultInitialValueForHiddenControl = "Blank Value";
int indexFromPreviousDataRetrieval = 1;
if (!String.Equals(hdnCurrentIndex.Value, defaultInitialValueForHiddenControl))
{
indexFromPreviousDataRetrieval = Convert.ToInt32(hdnCurrentIndex.Value, CultureInfo.InvariantCulture);
}
//Set property of user control
uclPager.PreviousIndex = indexFromPreviousDataRetrieval;
//Call method in user control
uclPager.PreAddAllLinks(tableDataCount, pageSize, indexFromPreviousDataRetrieval);
}
}
protected void btnSearch_Click(object sender, EventArgs e)
{
//When Search is clicked, reset the index to 1 (first page)
pageIndex = 1;
BindBusinessProcessActivitiesData();
}
protected void paginationLink_Click(object sender, EventArgs e)
{
//When link is clicked, set the pageIndex from user control property
pageIndex = uclPager.CurrentClickedIndex;
BindBusinessProcessActivitiesData();
}
private void BindBusinessProcessActivitiesData()
{
string name = txtEmpName.Text;
List<Employee> searchResult = DatabaseSimulator.GetData(name, pageSize, pageIndex).ToList();
grdEmployee.DataSource = searchResult;
grdEmployee.DataBind();
//Index
hdnCurrentIndex.Value = pageIndex.ToString(CultureInfo.InvariantCulture);
//Get total number of records
int tableDataCount = DatabaseSimulator.GetEmployeesCount(name);
uclPager.AddPageLinks(tableDataCount, pageSize, pageIndex);
}
}
Database Part
public static class DatabaseSimulator
{
public static IEnumerable<Employee> GetData(string name, int pageSize,int index)
{
IEnumerable<Employee> employeesSource = SearchEmployees(name);
int skipUpto = ((index-1) * pageSize);
IEnumerable<Employee> searchResult = employeesSource.Skip(skipUpto).Take(pageSize);
return searchResult;
}
public static int GetEmployeesCount(string name)
{
List<Employee> employees = GetEmployees();
int employeesCount = 0;
if (String.IsNullOrEmpty(name))
{
employeesCount = employees.Count;
}
else
{
List<Employee> selectedEmployees = employees.Where(r => r.Name == name).ToList();
employeesCount = selectedEmployees.Count;
}
return employeesCount;
}
private static IEnumerable<Employee> SearchEmployees(string name)
{
List<Employee> employees = GetEmployees();
if (String.IsNullOrEmpty(name))
{
return employees;
}
return employees.Where(r => r.Name == name);
}
private static List<Employee> GetEmployees()
{
List<Employee> employees = new List<Employee>();
for (int i = 1; i <= 400; i++)
{
Employee emp = new Employee();
emp.EmpID = i;
if (i % 2 == 0)
{
emp.Name = "Divisible by 2";
}
else if (i % 3 == 0)
{
emp.Name = "Divisible by 3";
}
else if (i % 5 == 0)
{
emp.Name = "Divisible by 5";
}
else if (i % 7 == 0)
{
emp.Name = "Divisible by 7";
}
else
{
emp.Name = "Other -- "+ i.ToString();
}
employees.Add(emp);
}
return employees;
}
}
public class Employee
{
public int EmpID { get; set; }
public string Name { get; set; }
}
Custom Paging in ASP.Net Web Application
I have following code for doing custom paging from an asp.net web application.
QUESTIONS
- Is there any pitfalls in this approach?
- Is there any improvement suggestions?
Helper Class
namespace WebApplication1
{
public static class PagingHelper
{
public static PagingInfo GetPageHyperlinks(int totalRecordsInTable, int pageSize, int currentIndex, string requestUrl)
{
PagingInfo pagingInfo = new PagingInfo();
pagingInfo.LinksToAdd = new Collection<HyperLink>();
string url = requestUrl;
int position = requestUrl.IndexOf('?');
if (position > 0)
{
url = requestUrl.Substring(0, position);
}
if (totalRecordsInTable > 0)
{
int itemsBeforeCurrentPage = 4;
int itemsAfterCurrentPage = 2;
int itemsCountInMiddleSection = itemsBeforeCurrentPage + 1 + itemsAfterCurrentPage;
//string templates for links
string link = "<a href='" + url + "?Index=[Index]&Size=[Size]'><span class='page-numbers'>##Text##</span></a>";
string link_pre = "<a href='" + url + "?Index=[Index]&Size=[Size]'><span class='page-numbers prev'>##Text##</span></a>";
string link_next = "<a href='" + url + "?Index=[Index]&Size=[Size]'><span class='page-numbers next'>##Text##</span></a>";
Double numberOfPagesRequired = Convert.ToDouble(totalRecordsInTable / pageSize);
if (totalRecordsInTable % pageSize != 0)
{
numberOfPagesRequired = numberOfPagesRequired + 1;
}
//Generate dynamic paging
int start;
if (currentIndex <= (itemsBeforeCurrentPage + 1))
{
start = 1;
}
else
{
start = currentIndex - itemsBeforeCurrentPage;
}
int lastAddedLinkIndex = 0;
int? firtsAddedLinkIndex = null;
for (int i = start; i < start + itemsCountInMiddleSection; i++)
{
if (i > numberOfPagesRequired)
{
//do not add more links if exceeded limit
continue;
}
//create dynamic HyperLinks
HyperLink lnk = new HyperLink();
lnk.ID = "lnk_" + i.ToString();
lnk.Text = i.ToString();
lnk.Text = i.ToString();
lastAddedLinkIndex = i;
if (firtsAddedLinkIndex == null)
{
firtsAddedLinkIndex = i;
}
//Check whetehr current page
if (i == currentIndex)
{
lnk.CssClass = "page-numbers current";
}
else
{
lnk.CssClass = "page-numbers";
lnk.NavigateUrl = url + "?Index=" + i + "&Size=" + pageSize + "";
}
pagingInfo.LinksToAdd.Add(lnk);
}
if (numberOfPagesRequired > itemsCountInMiddleSection)
{
//Set dots (ellipse) visibility
pagingInfo.IsEndDotsVisible = lastAddedLinkIndex == numberOfPagesRequired ? false : true;
pagingInfo.IsStartDotsVisible = firtsAddedLinkIndex <= 2 ? false : true;
//First and Last Page Links
pagingInfo.IsLastLinkVisible = lastAddedLinkIndex == numberOfPagesRequired ? false : true;
pagingInfo.IsFirstLinkVisible = firtsAddedLinkIndex == 1 ? false : true;
pagingInfo.LastLinkText = link.Replace("[Index]", numberOfPagesRequired.ToString()).Replace("[Size]", pageSize.ToString()).Replace("##Text##", numberOfPagesRequired.ToString());
pagingInfo.FirstLinkText = link.Replace("[Index]", (numberOfPagesRequired - numberOfPagesRequired + 1).ToString()).Replace("[Size]", pageSize.ToString()).Replace("##Text##", (numberOfPagesRequired - numberOfPagesRequired + 1).ToString());
}
//For first page, there is no previous
if (currentIndex != 1)
{
pagingInfo.PreviousLinkText = link_pre.Replace("[Size]", pageSize.ToString()).Replace("[Index]", (currentIndex - 1).ToString()).Replace("##Text##", "Prev");
}
else
{
//Hyperlink is replaced with text
pagingInfo.PreviousLinkText = "<span class='page-numbers prev'>Prev</span>";
}
//For last page there is no Next
if (currentIndex != Convert.ToInt32(numberOfPagesRequired))
{
pagingInfo.NextLinkText = link_next.Replace("[Size]", pageSize.ToString()).Replace("[Index]", (currentIndex + 1).ToString()).Replace("##Text##", "Next");
}
else
{
//Hyperlink is replaced with text
pagingInfo.NextLinkText = "<span class='page-numbers next'>Next</span>";
}
}
return pagingInfo;
}
}
}
Data Transfer Class
public class PagingInfo
{
public Collection<HyperLink> LinksToAdd { get; set; }
public bool? IsEndDotsVisible { get; set; }
public bool? IsStartDotsVisible { get; set; }
public bool? IsFirstLinkVisible { get; set; }
public bool? IsLastLinkVisible { get; set; }
public string FirstLinkText { get; set; }
public string LastLinkText { get; set; }
public string PreviousLinkText { get; set; }
public string NextLinkText { get; set; }
}
Code Behind
namespace WebApplication1
{
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
int size = 0; int index = 0;
if (!Page.IsPostBack)
{
string test = this.Page.Request.Url.ToString();
string sizeTest = Request["Size"];
string indexTest = Request["Index"];
size = string.IsNullOrEmpty(Request["Size"]) ? 5 : Convert.ToInt32(Request["Size"]);
index = string.IsNullOrEmpty(Request["Index"]) ? 1 : Convert.ToInt32(Request["Index"]);
//load data from database
BindGrid(size, index);
}
}
void BindGrid(int pageSize, int index)
{
try
{
string ConnStr = "Data Source=.;Initial Catalog=LibraryReservationSystem;Integrated Security=True;Connect Timeout=30";
//the sql query with paging logics
String SQL = @"select * from
(SELECT ROW_NUMBER() OVER (ORDER BY EmpID asc) as row,*
FROM Employee) tblTemp
WHERE row between (" + index + " - 1) * " + pageSize + " + 1 and " + index + "*" + pageSize + " ";
SQL += " select COUNT(*) from Employee";
//fetching data from database suing SqlDataAdapter Fill method to bind the Gridview
SqlDataAdapter ad = new SqlDataAdapter(SQL, ConnStr);
DataSet ds = new DataSet();
ad.Fill(ds);
this.gvPaging.DataSource = ds.Tables[0];
this.gvPaging.DataBind();
DataTable tableForData = ds.Tables[0];
DataTable tableForRowCount = ds.Tables[1];
int totalRecordsInTable = Convert.ToInt32(tableForRowCount.Rows[0][0]);
PagingInfo info = PagingHelper.GetPageHyperlinks(totalRecordsInTable, pageSize, index, this.Page.Request.Url.ToString());
if(info.LinksToAdd!=null)
{
foreach (HyperLink link in info.LinksToAdd)
{
this.pl.Controls.Add(link);
}
}
//Dots visiblity
if (info.IsEndDotsVisible != null)
{
spDot2.Visible = Convert.ToBoolean(info.IsEndDotsVisible);
}
if (info.IsStartDotsVisible != null)
{
spDot1.Visible = Convert.ToBoolean(info.IsStartDotsVisible);
}
//First and Last Links
if (info.IsFirstLinkVisible != null)
{
lblIst.Visible = Convert.ToBoolean(info.IsFirstLinkVisible);
lblIst.Text = info.FirstLinkText;
}
if (info.IsLastLinkVisible != null)
{
lblLast.Visible = Convert.ToBoolean(info.IsLastLinkVisible);
lblLast.Text = info.LastLinkText;
}
//Pre and Next
lblpre.Text = info.PreviousLinkText;
lblnext.Text = info.NextLinkText;
}
catch (Exception ee)
{
//catch the exception
}
}
}
}
MARK UP
<form runat="server">
<input type="hidden" runat="server" id="hdSize" />
<div>
<asp:GridView ID="gvPaging" runat="server" AutoGenerateColumns="false" GridLines="None">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<table>
<tr>
<td class="text">
Emp ID:
</td>
<td align="left" colspan="5">
<%# Eval("EmpID")%>
</td>
<td align="left" colspan="4" class="text">
Name:
</td>
<td>
<%# Eval("Name")%>
</td>
</tr>
</table>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<div class="fl">
<asp:Label runat="server" ID="lblpre"></asp:Label>
<asp:Label runat="server" ID="lblIst" Visible="false"></asp:Label>
<asp:Label runat="server" ID="spDot1" CssClass="page-numbers prev" Visible="false"
Text="..."></asp:Label>
<asp:PlaceHolder ID="pl" runat="server"></asp:PlaceHolder>
<asp:Label runat="server" ID="spDot2" Visible="false" CssClass="page-numbers prev"
Text="..."></asp:Label>
<asp:Label runat="server" ID="lblLast" Visible="false"></asp:Label>
<asp:Label runat="server" ID="lblnext"></asp:Label>
</div>
</div>
</form>
CSS
.page-numbers
{
border: 1px solid #CCC;
color: #808185;
display: block;
float: left;
font-size: 9pt;
margin-right: 3px;
padding: 4px 4px 3px;
text-decoration: none;
}
.page-numbers.current
{
background-color: #808185;
border: 1px solid #808185;
color: white;
font-weight: bold;
}
.page-numbers.next, .page-numbers.prev
{
border: 1px solid white;
font-size: 12pt;
}