The simplest way to perform paging and sorting in an ASP.Net webforms application is to use the SQLDatasource control. If you do not use the suite of DataSource controls paging and sorting can manually be achieved without too much extra work.
The page contains a GridView control that has paging and sorting enabled by setting AllowPaging and AllowSorting attributes to true. Height and width are optional.
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" Height="292px" OnDataBound="GridView1_DataBound" OnPageIndexChanging="GridView1_PageIndexChanging" OnSorting="GridView1_Sorting" Width="600px"></asp:GridView>
As I am not using any data access methods, I have created a private method to generate and return a DataTable of data.
private DataTable GetTableData()
{
DataTable dt = new DataTable();
dt.Columns.Add("ProductId", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("ProductNumber", typeof(string));
dt.Columns.Add("Quantity", typeof(int));
dt.Columns.Add("UnitPrice", typeof(decimal));
Random rnd = new Random();
for (var i = 1; i <= 100; i++)
{
var qty = rnd.Next(1, 100);
DataRow dr = dt.NewRow();
dr["ProductId"] = i;
dr["Name"] = $"Product{i}";
dr["ProductNumber"] = $"A-{qty}";
dr["Quantity"] = qty;
dr["UnitPrice"] = i;
dt.Rows.Add(dr);
}
return dt;
}
The webform has two properties that are used as accessors to values stored in viewstate, the name of the sort column and the sort direction.
public string SortColumn
{
get {return Convert.ToString(ViewState["SortColumn"]);}
set {ViewState["SortColumn"] = value;}
}
public string SortDirection
{
get { return Convert.ToString(ViewState["SortDirection"]); }
set { ViewState["SortDirection"] = value; }
}
In the page load method, if the page load was not from a postback the default sort direction and sort column is set and the BindGrid method is called.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
SortDirection = "ASC";
SortColumn = "ProductId";
BindGrid();
}
}
The Bind Grid method calls the GetTableData method to generate the data and the data is bound to the grid.
private void BindGrid()
{
var dt = GetTableData();
if (dt != null)
{
//Sort the data.
dt.DefaultView.Sort = SortColumn + " " + SortDirection;
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
The PageIndexChanging event is raised when one of the pager options is clicked, but before the GridView handles the paging operation. Notice the BindGrid method is called causing the grid to be rebound to the data.
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
BindGrid();
}
The Sorting event is raised when the column header link is clicked, but before the GridView control handles the sort operation. Here the sort expression, in this case the data column to sort by and the sort order are set. The data is then rebound by calling the BindGrid method.
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
SortDirection = (SortDirection == "ASC") ? "DESC" : "ASC";
SortColumn = e.SortExpression ;
BindGrid();
}
The DataBound event fires when all the databinding for the GridView is finished. All we do here is find the index of the GridView column that matches the sort expression and add an image to the column header to indicate the current sort direction.
protected void GridView1_DataBound(object sender, EventArgs e)
{
int columnIndex = 0;
foreach (DataControlFieldHeaderCell headerCell in GridView1.HeaderRow.Cells)
{
if (headerCell.ContainingField.SortExpression == SortColumn)
{
columnIndex = GridView1.HeaderRow.Cells.GetCellIndex(headerCell);
break;
}
}
Image sortImage = new Image();
sortImage.ImageUrl = string.Format("images/sort-{0}ending.png", SortDirection);
GridView1.HeaderRow.Cells[columnIndex].Controls.Add(sortImage);
}
That is pretty much it.
