5
votes

I'm new to Asp.net and I'm currently working with GridViews. I've looked around this site and others have seen tips for how to add sorting arrows to column headers.

So far I've done this:

Set these GridView properties:

SortedAscendingHeaderStyle-CssClass="sortasc"
SortedDescendingHeaderStyle-CssClass="sortdesc"

And my css has this:

th.sortasc a  
{
   display:block; padding:0 4px 0 15px; 
   background:url("images/icons/ascArrow.png") no-repeat;
}

th.sortdesc a 
{
   display:block; padding:0 4px 0 15px; 
  background:url("images/icons/descArrow.png") no-repeat;
}

This works great to show an image after the user clicks a header and the column sorts.

The issue I'm having now, is that I'd like the columns to show images by default so that users can know that they can click them to sort. Is there a way to accomplish this?

3

3 Answers

10
votes

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

AnswerSource

1
votes

I used the following method... Same as accepted answer but using characters instead of images. Sharing in case it helps someone else.

protected void GrdOverview_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];

                string sortDir = ViewState["SortDirection"] != null ? ViewState["SortDirection"].ToString() : "ASC";
                string sortBy = ViewState["SortExpression"] != null ? ViewState["SortExpression"].ToString() : "---";

                if (lnk != null && sortBy == lnk.CommandArgument)
                {
                    string sortArrow = sortDir == "ASC" ? " ▲" : " ▼";
                    lnk.Text += sortArrow;
                }
            }
        }
    }
}
0
votes

From your question:"To show images by default so that users can know that they can click them to sort." Add a HeaderStyle-CssClass property to your gridview, and put the default style in that property:

<asp:GridView ID="GridView1" runat="server"
                        AutoGenerateColumns="False"
                        AllowSorting="True"
                        OnSorting="GridView1_Sorting"
                        HeaderStyle-CssClass ="headRowSortable">

...and add corrosponding CSS with your Up-Down sortable icon:

.headRowSortable > th > a {
        display: inline-block;
        padding-left: 15px;
        background: url('../Images/up-down-sort.png') left center no-repeat;
        background-size: contain;
        text-decoration: none;
        vertical-align: central;
    }

Which will work great as long as you are using an <asp:SQLDataSource>...which I am guessing you are.

As soon as you start binding the DataGrid to a Data Source in code, the GridView will stop applying the SortedAscendingHeaderStyle and SortedDescendingHeaderStyle because it won't know which column got sorted which way.

So in the case that you are doing your own data binding, you need to change the classes on the columns during the GridView_Sorting event:

protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
        {
            //get the index of the column we sorted.
            int iSortedColIdx = 0;
            foreach (DataControlField c in GridView1.Columns)
            {
                if (c.SortExpression == e.SortExpression)
                    break;
                iSortedColIdx++;
            }

            string sSortDirection = "";
            if ((string)ViewState["SortColumn"] == e.SortExpression)
                sSortDirection = ((string)ViewState["SortDirection"] == "") ? " DESC" : "";
            else
                ViewState["SortColumn"] = e.SortExpression;

            ViewState["SortDirection"] = sSortDirection;


            DataTable oDT = (DataTable)ViewState["MyDataSource"];
            if (oDT.Rows.Count > 0)
            {
                string sSortString = e.SortExpression + sSortDirection;
                oDT.DefaultView.Sort = sSortString;

                GridView1.DataSource = oDT;
                GridView1.DataBind();

                // SET THE HEADER CSSCLASS AFTER THE DATA BIND. IT'LL GET CLEARED ON DATA BIND.
                GridView1.HeaderRow.Cells[iSortedColIdx].CssClass = sSortDirection == "" ? "headRowSortAsc" : "headRowSortDesc";
            }

        }

... and the corrosponding css:

th.headRowSortAsc a {
    display: inline-block;
    padding-left: 15px;
    background: url("../Images/down-sort.png") no-repeat;
    background-size: 15px;
    background-size: contain;
    text-decoration: none;
    vertical-align: central;
}

th.headRowSortDesc a {
    display: inline-block;
    padding-left: 15px;
    background: url("../Images/up-sort.png") no-repeat;
    background-size: 15px;
    background-size: contain;
    text-decoration: none;
    vertical-align: central;
}