Sorting GridView with LINQ and adding Sort Image URL in ASP.NET
Introduction:
This article explains how to sort GridView without getting sorted resultset from database thereby saving a database hit. Example in this article uses a GridView with three columns.
Background:
Showing images to denote the column sorted and sort direction helps user differentiate sorted column from others. Images can be added to header in different ways. One way is keeping a Panel in HeaderTemplate and adding Images dynamically. Another simple way is inserting image HTML in Header Text along with Header Text in Data Binding Event.
Markup:
<form id="form1" runat="server"> <asp:ScriptManager ID="sc" runat="server" EnablePartialRendering="true"> </asp:ScriptManager> <asp:UpdatePanel ID="up" runat="server"> <ContentTemplate> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4" AllowSorting="true" ForeColor="#333333" Font-Names="Tahoma" Font-Size="Small" GridLines="None" OnSorting="GridView1_Sorting" RowStyle-VerticalAlign="Top" OnDataBinding="GridView1_DataBinding"> <AlternatingRowStyle BackColor="White" /> <Columns> <asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" HtmlEncode="false" ItemStyle-VerticalAlign="Top" /> <asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName" HtmlEncode="false" ItemStyle-VerticalAlign="Top" /> <asp:BoundField DataField="LastName" HeaderText="Last Name" SortExpression="LastName" HtmlEncode="false" ItemStyle-VerticalAlign="Top" /> </Columns> <EditRowStyle BackColor="#2461BF" /> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> <RowStyle BackColor="#EFF3FB" /> <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> </asp:GridView> </ContentTemplate> </asp:UpdatePanel> </form>
CodeBehind:
public string GridViewSortExpression { get { return ViewState["GridViewSortExpression"] == null ? "ID" : ViewState["GridViewSortExpression"] as string; } set { ViewState["GridViewSortExpression"] = value; } } public SortDirection GridViewSortOrder { get { return ViewState["GridViewSortOrder"] == null ? SortDirection.Ascending : (SortDirection)ViewState["GridViewSortOrder"]; } set { ViewState["GridViewSortOrder"] = value; } } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { GridView1.DataSource = new[] { new { ID = 1, FirstName = "Mike", LastName = "Waugh" }, new { ID = 2, FirstName = "Allen", LastName = "Deblase" }, new { ID = 3, FirstName = "John", LastName = "Kennedy" }, new { ID = 4, FirstName = "Ricardo", LastName = "Powell" }, new { ID = 5, FirstName = "Adams", LastName = "Brian" }, new { ID = 6, FirstName = "Jerico", LastName = "Chris" }, new { ID = 7, FirstName = "Samuel", LastName = "Martin" } }; GridView1.DataBind(); } } protected void GridView1_Sorting(object sender, GridViewSortEventArgs e) { //Get existing rows var rows = GridView1.Rows.Cast<GridViewRow>().Select(a => new { ID = Convert.ToInt32(a.Cells[0].Text), FirstName = a.Cells[1].Text, LastName = a.Cells[2].Text }).ToList(); //Check if the same column is sorted to switch Sort Order if (GridViewSortExpression.Equals(e.SortExpression)) GridViewSortOrder = GridViewSortOrder.Equals(SortDirection.Ascending) ? SortDirection.Descending : SortDirection.Ascending; else GridViewSortOrder = SortDirection.Ascending; //save Sort Expression and Sort Order GridViewSortExpression = e.SortExpression; if (GridViewSortOrder.Equals(SortDirection.Ascending)) GridView1.DataSource = rows.OrderBy(a => a.GetType().GetProperty(GridViewSortExpression).GetValue(a, null)); else GridView1.DataSource = rows.OrderByDescending(a => a.GetType().GetProperty(GridViewSortExpression).GetValue(a, null)); GridView1.DataBind(); } protected void GridView1_DataBinding(object sender, EventArgs e) { foreach (DataControlField column in GridView1.Columns) { //Remove Previous Sort Image column.HeaderText = Regex.Replace(column.HeaderText, "<[^>]*>", "", RegexOptions.IgnoreCase); if (column.SortExpression.Equals(GridViewSortExpression)) { //set new sort image string strSortImageURL = GridViewSortOrder == SortDirection.Descending ? "<img border=\"0\" style=\"background-color:White;vertical-align:bottom;\" src=\"Images/desc.gif\"/>" : "<img border=\"0\" style=\"background-color:White;vertical-align:bottom;\" src=\"Images/asc.gif\"/>"; column.HeaderText = String.Format("{0}{1}", strSortImageURL, column.HeaderText); } } }
Description:
SortExpression and
SortOrder needs to be preserved in ViewState to switch sorting order
according to the column clicked. GridView can be sorted by sort
expression using Dynamic Lambda Expression or Reflection. In this
example, I have used Reflection to substitute Column Value dynamically
from Sort Expression instead of wrting if else statements to check for
column sort expression.
Comments