Aximili
Aximili

Reputation: 29484

ASP.NET GridView SortedAscendingHeaderStyle does not work

My SortedAscendingHeaderStyle and SortedDescendingHeaderStyle is not working at all

<asp:GridView ID="grdProducts" runat="server" CssClass="grid" AllowPaging="True" AllowSorting="True" PageSize="100" EmptyDataText="No data to show"
              onrowdatabound="grdProducts_RowDataBound"  onrowediting="grdProducts_RowEditing" onsorting="grdProducts_Sorting" AutoGenerateEditButton="True">
  <AlternatingRowStyle CssClass="even" />
  <SortedAscendingHeaderStyle ForeColor="White" CssClass="sorted" />
  <SortedDescendingHeaderStyle CssClass="sorted desc" />
</asp:GridView>

Rows are sorted correctly when headers are clicked, but when I inspect the header using FireBug, it only shows: (this is when sorted ascending)

<th scope="col">
  <a href="javascript:__doPostBack('ctl00$body$ctl00$grdProducts','Sort$Namekey')">Namekey</a>
</th>

ForeColor and CssClass are not set at all.

Anyone has any idea what I am doing wrong?

EDIT: My C# code behind

  protected void grdProducts_Sorting(object sender, GridViewSortEventArgs e)
  {
    if ((string)ViewState["SortColumn"] == e.SortExpression)
      ViewState["SortDirection"] = ((string)ViewState["SortDirection"] == "") ? " DESC" : "";
    else
    {
      ViewState["SortColumn"] = e.SortExpression;
      ViewState["SortDirection"] = "";
    }
  }

  protected override void OnPreRender(EventArgs e)
  {
    BindGrid();
    base.OnPreRender(e);
  }

  private void BindGrid()
  {
    string query = "SELECT ... ORDER BY " + ViewState["SortColumn"] + ViewState["SortDirection"];

    DataTable dt = SqlFunctions.Select(query);
    grdProducts.DataSource = dt;
    grdProducts.DataBind();
  }

Upvotes: 9

Views: 11890

Answers (4)

Marcel
Marcel

Reputation: 15732

Super-late, but for reference. It works for me, using the following:

Here's my code (in x.aspx):

<asp:SqlDataSource ID="SqlDataSourceX" runat="server" ConnectionString="xxx"
    EnableViewState="False" OnSelecting="SqlDataSourceXSelecting"></asp:SqlDataSource>

<asp:GridView ....
    AllowSorting="True"
    EnableSortingAndPagingCallbacks="False"
    OnSorted="GridViewResults_OnSorted" ....           DataSourceID="SqlDataSourceX" CssClass="table table-bordered text-left">
    <SortedAscendingHeaderStyle CssClass="SortedAscendingHeaderStyle"></SortedAscendingHeaderStyle>
    <SortedDescendingHeaderStyle CssClass="SortedDescendingHeaderStyle"></SortedDescendingHeaderStyle>
    <Columns>

...

Here's my code (in x.aspx.cs):

protected void GridViewResults_OnSorted(object sender, EventArgs e) {
   ExecuteSearch(); //Adds some where clauses to the SQL Data Source, no explicit sorting here
}

This then creates the following table headers, after clicking for sort:

<th class="SortedDescendingHeaderStyle" scope="col">
    <a href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$GridViewResults','Sort$LocalUnitId')">BUR Nummer</a>
</th>

Upvotes: 0

brentj
brentj

Reputation: 121

I don't have enough rep to comment on the accepted answer. When I tried applying the solution, it would sort properly, but did not apply the CSS class to what was eventually rendered.

In my case, invoking DataBind() on my grid AFTER sorting my DataSource (List) and assigning it as the grid's DataSource, but BEFORE setting the CssClass did the trick. Figured I'd share in case someone else encountered something similar.

Upvotes: 6

jim31415
jim31415

Reputation: 8818

I'm not sure if SortedDescendingHeaderStyle works without code if you're not using an asp:SQLDataSource as your GridView data source. But a little coding can get you there.

You need to apply the CSS style manually to the header cell. You can do it in the Sorting event.

protected void grdProducts_Sorting(object sender, GridViewSortEventArgs e)
{
   if ((string)ViewState["SortColumn"] == e.SortExpression)
   {
      ViewState["SortDirection"] = ((string)ViewState["SortDirection"] == "") ? " DESC" : "";
      grdProducts.HeaderRow.Cells[GetColumnIndex( e.SortExpression )].CssClass = "AscendingHeaderStyle";
   }
   else
   {
      ViewState["SortColumn"] = e.SortExpression;
      ViewState["SortDirection"] = "";
      grdProducts.HeaderRow.Cells[GetColumnIndex( e.SortExpression )].CssClass = "DescendingHeaderStyle";
   }
   BindGrid();
}




private int GetColumnIndex( string SortExpression )
{
    int i = 0;
    foreach( DataControlField c in gvwCustomers.Columns )
    {
        if( c.SortExpression == SortExpression )
            break;
        i++;
    }
    return i;
}

Upvotes: 14

rick schott
rick schott

Reputation: 21137

I think it's the timing of your databinding. Change your databinding to work like this:

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

  protected void grdProducts_Sorting(object sender, GridViewSortEventArgs e)
  {
    if ((string)ViewState["SortColumn"] == e.SortExpression)
      ViewState["SortDirection"] = ((string)ViewState["SortDirection"] == "") ? " DESC" : "";
    else
    {
      ViewState["SortColumn"] = e.SortExpression;
      ViewState["SortDirection"] = "";
    }
    BindGrid();
  }

GridView.Sorting Event

Upvotes: 0

Related Questions