Support us .Net Basics C# SQL ASP.NET ADO.NET MVC Slides C# Programs Subscribe Buy DVD

How to include sort arrows when sorting an asp.net gridview control - Part 49

Suggested Videos 
Part 46 - Sorting a gridview that uses objectdatasource control and business objects
Part 47 - Sorting a gridview that does not use any datasource control
Part 48 - Sorting an asp.net gridview in ascending and descending order



In this video we will discuss about including sort arrows, when sorting an asp.net gridview control. When the data is sorted in ascending order, we want to show UP ARROW and if the data is sorted in descending order we want to show DOWN ARROW.



Employee data sorted by name in ascending order
Employee data sorted by name in ascending order

Employee data sorted by name in descending order
Employee data sorted by name in descending order

Please watch Part 48, before proceeding with this video.

Step 1: Drag and drop a gridview on webform1.aspx

Step 2: Add a class file with name = "EmployeeDataAccessLayer.cs". Copy and paste the following code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace Demo
{
    public class Employee
    {
        public int EmployeeId { get; set; }
        public string Name { get; set; }
        public string Gender { get; set; }
        public string City { get; set; }
    }

    public class EmployeeDataAccessLayer
    {
        public static List<Employee> GetAllEmployees(string sortColumn)
        {
            List<Employee> listEmployees = new List<Employee>();

            string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
            using (SqlConnection con = new SqlConnection(CS))
            {
                string sqlQuery = "Select * from tblEmployee";

                if (!string.IsNullOrEmpty(sortColumn))
                {
                    sqlQuery += " order by " + sortColumn;
                }

                SqlCommand cmd = new SqlCommand(sqlQuery, con);

                con.Open();
                SqlDataReader rdr = cmd.ExecuteReader();
                while (rdr.Read())
                {
                    Employee employee = new Employee();
                    employee.EmployeeId = Convert.ToInt32(rdr["EmployeeId"]);
                    employee.Name = rdr["Name"].ToString();
                    employee.Gender = rdr["Gender"].ToString();
                    employee.City = rdr["City"].ToString();

                    listEmployees.Add(employee);
                }
            }

            return listEmployees;
        }
    }
}

Step 3: Generate event handler methods, for the following events of GridView1 control
Sorting
RowCreated

Step 4: Flip webform1.aspx to html source mode and set the following 2 custom attributes on GridView1 control.
CurrentSortField="EmployeeId" 
CurrentSortDirection="ASC"

At this point the HTML of your webform, should be as shown below.
<asp:GridView ID="GridView1" 
    runat="server" 
    AllowSorting="True" 
    onsorting="GridView1_Sorting"
    CurrentSortField="EmployeeId" 
    CurrentSortDirection="ASC"
    OnRowCreated="GridView1_RowCreated">
</asp:GridView>

Step 5: Copy and paste the following code in WebForm1.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Demo
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                GridView1.DataSource = EmployeeDataAccessLayer.GetAllEmployees("EmployeeId");
                GridView1.DataBind();
            }
        }
        protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
        {
            //Response.Write("Sort Expression = " + e.SortExpression);
            //Response.Write("<br/>");
            //Response.Write("Sort Direction = " + e.SortDirection.ToString());

            SortDirection sortDirection = SortDirection.Ascending;
            string sortField = string.Empty;

            SortGridview((GridView)sender, e, out sortDirection, out sortField);
            string strSortDirection = sortDirection == SortDirection.Ascending ? "ASC" : "DESC";

            GridView1.DataSource = EmployeeDataAccessLayer.GetAllEmployees(e.SortExpression + " " + strSortDirection);
            GridView1.DataBind();
        }
        protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
        {
            if (GridView1.Attributes["CurrentSortField"] != null && GridView1.Attributes["CurrentSortDirection"] != null)
            {
                if (e.Row.RowType == DataControlRowType.Header)
                {
                    foreach (TableCell tableCell in e.Row.Cells)
                    {
                        if (tableCell.HasControls())
                        {
                            LinkButton sortLinkButton = null;
                            if (tableCell.Controls[0] is LinkButton)
                            {
                                sortLinkButton = (LinkButton)tableCell.Controls[0];
                            }

                            if (sortLinkButton != null && GridView1.Attributes["CurrentSortField"] == sortLinkButton.CommandArgument)
                            {
                                Image image = new Image();
                                if (GridView1.Attributes["CurrentSortDirection"] == "ASC")
                                {
                                    image.ImageUrl = "~/Images/up_arrow.png";
                                }
                                else
                                {
                                    image.ImageUrl = "~/Images/down_arrow.png";
                                }
                                tableCell.Controls.Add(new LiteralControl("&nbsp;"));
                                tableCell.Controls.Add(image);
                            }
                        }
                    }
                }
            }
        }
        private void SortGridview(GridView gridView, GridViewSortEventArgs e, out SortDirection sortDirection, out string sortField)
        {
            sortField = e.SortExpression;
            sortDirection = e.SortDirection;

            if (gridView.Attributes["CurrentSortField"] != null && gridView.Attributes["CurrentSortDirection"] != null)
            {
                if (sortField == gridView.Attributes["CurrentSortField"])
                {
                    if (gridView.Attributes["CurrentSortDirection"] == "ASC")
                    {
                        sortDirection = SortDirection.Descending;
                    }
                    else
                    {
                        sortDirection = SortDirection.Ascending;
                    }
                }

                gridView.Attributes["CurrentSortField"] = sortField;
                gridView.Attributes["CurrentSortDirection"] = (sortDirection == SortDirection.Ascending ? "ASC" : "DESC");
            }
        }
    }
}

Images used in the demo.



1 comment:

  1. Hi Venkat,
    all your lessons are instructive and from pedagogical point of view flawless, thank you indeed!
    When I follow your examples I always try to do it in active mode, that's why, as an exercise, I always try to improve something or make it work better or in alternative way, because the exercises serve also to this, isn't it? :)
    For example, in this case, instead of arrows images I've used two special characters which have an acceptable appearance and there is no problem with their size nor color (as in case of an external image) because each of them becomes a part of linkbutton text. Adding some characters in code is also less time consuming than the loading an external image even if, in this case, the time is really insignificant...
    Here are the two instructions:
    upward arrow : sortLinkButton.Text += " \u25B2";
    downward arrow: sortLinkButton.Text += " \u25BC";

    And here is the entire piece of code in which I also have done some other small improvements :)

    protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
    {
    if (e.Row.RowType == DataControlRowType.Header) {
    if (GridView1.Attributes["CurrentSortField"] != null && GridView1.Attributes["CurrentSortDirection"] != null) {
    foreach (TableCell tableCell in e.Row.Cells) {
    if (tableCell.HasControls()) {
    if (tableCell.Controls[0] is LinkButton) {
    LinkButton sortLinkButton = (LinkButton)tableCell.Controls[0];
    if (GridView1.Attributes["CurrentSortField"] == sortLinkButton.CommandArgument) {
    if (GridView1.Attributes["CurrentSortDirection"] == "ASC") {
    sortLinkButton.Text += " \u25B2"; // upward char
    } else {
    sortLinkButton.Text += " \u25BC"; // downward char
    }
    break;
    }
    }
    }
    }
    }
    }
    }

    I only don't understand why this event method is called always twice every time the change is made...
    By the way, is it possible to set, in this example, the different header text, different from the sort column name?

    ReplyDelete

If you like this website, please share with your friends on facebook and Google+ and recommend us on google using the g+1 button on the top right hand corner.