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

Popular posts from this blog

Delete Confirmation for Delete ButtonField, TemplateField and CommandField in a GridView in ASP.NET

Selecting/Deselecting all CheckBoxes inside a ListView In ASP.NET

How to Create 3 Tier Vb.Net Desktop Application