Rahul Chowdhury
Rahul Chowdhury

Reputation: 1158

Multiple column sorting in Gridview?

Hi I want to Sort Multiple column In a gridview like shown here Hierarchical (Multi-column) Sorting for the .net GridView?

I did my home work My aspx looks like

<%@ Page Language="C#" AutoEventWireup="True" CodeBehind="Default.aspx.cs" Inherits="_Default" %>

<!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 id="Head1" runat="server">
    <title>Multiple sorting with Gridview</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True" 
            AllowSorting="true" onsorting="GridView1_Sorting" style="margin-right: 541px" 
            Width="873px">
        </asp:GridView>
        <p><asp:Label runat="server" ID="lblSortExpression" /></p>
    </div>
    </form>

</body>
</html>

In my Aspx.cs page

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Text;
using System.Web.UI.WebControls;
using System.Data.SqlClient;

partial class _Default : System.Web.UI.Page
{

    private ListDictionary m_ldSortExpression;
    private ListDictionary SortExpressions
    {
        get
        {
            m_ldSortExpression = (ListDictionary)ViewState["SortExpressions"];
            if (m_ldSortExpression == null)
            {
                m_ldSortExpression = new ListDictionary();
            }
            return m_ldSortExpression;
        }
        set { ViewState["SortExpressions"] = value; }
    }

    protected void Page_Load(object sender, System.EventArgs e)
    {
        if (!IsPostBack)
        {
            BindData();
        }
    }

    public void BindData()
    {
        // Usually you would get the data from the database.
        // To simplify the code, I will just fill a datatable with some standard data.
        DataTable dt = new DataTable();
        dt.Columns.Add("FirstName");
        dt.Columns.Add("LastName");
        dt.Columns.Add("Age");
        dt.Columns.Add("Position");

        dt.Rows.Add(new object[] {
            "1",
            "2",
            28,
            "5"
        });
        dt.Rows.Add(new object[] {
            "2",
            "8",
            31,
            "2"
        });
        dt.Rows.Add(new object[] {
            "2",
            "4",
            31,
            "4"
        });
        dt.Rows.Add(new object[] {
            "3",
            "7",
            37,
            "3"
        });
        dt.Rows.Add(new object[] {
            "4",
            "4",
            40,
            "1"
        });

        DataView dv = dt.DefaultView;
        // use a stringbuilder to hold the sortexpression for the dataview
        StringBuilder sbSortExpression = new StringBuilder();
        if (SortExpressions.Count > 0)
        {
            string[] myKeys = new string[SortExpressions.Count + 1];
            SortExpressions.Keys.CopyTo(myKeys, 0);
            for (int i = 0; i <= SortExpressions.Count - 1; i++)
            {
                sbSortExpression.Append(myKeys[i]);
                sbSortExpression.Append(" ");
                sbSortExpression.Append(SortExpressions[myKeys[i]]);
                if (i != SortExpressions.Count - 1)
                {
                    sbSortExpression.Append(", ");
                }

            }
            lblSortExpression.Text = sbSortExpression.ToString();

            // usually we would send that sort-expression now to SQL via some stored-procedure
            dv.Sort = sbSortExpression.ToString();
        }
        else
        {
            lblSortExpression.Text = string.Empty;
        }

        GridView1.DataSource = dv;
        GridView1.DataBind();
        PositionGlyph(GridView1, dv.Sort.ToString(), dt);


    }

    private void PositionGlyph(GridView GridView1, string p,DataTable dt)
    {
        if ((GridView1.Rows.Count == 0) || (string.IsNullOrEmpty(p)))
            return;

        Image glyph = new Image();
        glyph.EnableTheming = false;

        string[] words = p.Split(',');

        foreach (string word in words)
        {
            string[] SortType = word.Split(' ');
            if (SortType[SortType.Length - 1] == SortOrder.Ascending.ToString().Substring(0, 3).ToUpper())
                glyph.ImageUrl = "~/Images/down_arrow.png";

            else
                glyph.ImageUrl = "~/Images/up_arrow.png";

            int columnindex = dt.Columns[SortType[SortType.Length - 2].ToString()].Ordinal;
            GridView1.HeaderRow.Cells[columnindex].Controls.Add(glyph);
            //for (int x = 0; x < dt.Columns.Count; x++)
            //{
            //    if (SortType[SortType.Length - 2].ToString()== dt.Columns[x].ColumnName)
            //    {
            //        GridView1.HeaderRow.Cells[x].Controls.Add(glyph);
            //        break;
            //    }
            //}

        }

    }

    protected void GridView1_Sorting(object sender, System.Web.UI.WebControls.GridViewSortEventArgs e)
    {
        m_ldSortExpression = SortExpressions;

        if (!m_ldSortExpression.Contains(e.SortExpression))
        {
            m_ldSortExpression.Add(e.SortExpression, e.SortDirection.ToString().Replace("Ascending", "ASC").Replace("Descending", "DESC"));
        }
        else
        {
            // Get sort direction
            string strSortDirection = m_ldSortExpression[e.SortExpression].ToString();
            // Was it ascending?
            if (strSortDirection == "ASC")
            {
                // Yes, so sort in desc
                m_ldSortExpression[e.SortExpression] = "DESC";
            }
            else if (strSortDirection == "DESC")
            {
                // it is descending
                // remove the sort order
                m_ldSortExpression.Remove(e.SortExpression);
            }
        }

        SortExpressions = m_ldSortExpression;
        BindData();
    }
    public _Default()
    {
        Load += Page_Load;
    }

}

Everything is working fine even multiple sorting but sort arrow in column header is not showing properly.I think issue is in PositionGlyph Method.Asc or Desc arrow is showing only for last clicked header.I want to show sort direction for all the columns.Please help me on the same

Upvotes: 2

Views: 11937

Answers (2)

Sharique Hussain Ansari
Sharique Hussain Ansari

Reputation: 1456

Use This:

DataView m_DataView = new DataView(dt);
m_DataView.Sort =ColumnName1 + " ASC, " + ColumnName2 + " ASC, " + ColumnName3 + " ASC";

Hope this help.

Upvotes: 1

Ramesh Rajendran
Ramesh Rajendran

Reputation: 38713

you can show the arrow for sorting behavior of a gridview column in the RowCreated event something like this i usually do it this way

protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.Header)
    {
        foreach (TableCell tc in e.Row.Cells)
        {
            if (tc.HasControls())
            {
                // search for the header link
                LinkButton lnk = (LinkButton)tc.Controls[0];
                if (lnk != null && GridView1.SortExpression == lnk.CommandArgument)
                {
                    // inizialize a new image
                    System.Web.UI.WebControls.Image img = new System.Web.UI.WebControls.Image();
                    // setting the dynamically URL of the image
                    img.ImageUrl = "~/img/ico_" + (GridView1.SortDirection == SortDirection.Ascending ? "asc" : "desc") + ".gif";
                    // adding a space and the image to the header link
                    tc.Controls.Add(new LiteralControl(" "));
                    tc.Controls.Add(img);

                }
            }
        }
    }
}

it also toggles the image on ascending and descending sort orders of column

What the code actually do is it loops through the GridView Header to search a LinkButton (the Framework creates it only if the SortExpression property is set). Then, if the found LinkButton is the sorted field, then it shows the image to the output, that's all

Please see this sample

Upvotes: 0

Related Questions