10

I have a simple gridview control bound to an sql datasource. Now I enabled sorting, but when I click on a column to be sorted, it sorts it in an Ascending Order first. When I click the same column again, it sorts it in a Descending order. I want to switch that around. I want it to sort Descending on the first click, and Ascending the second. How do I do that?

Here is my Gridview Control code:

<asp:GridView ID="GridView1" runat="server" AllowSorting="True" 
        AutoGenerateColumns="False" BackColor="White" BorderColor="#999999" 
        BorderStyle="Solid" BorderWidth="1px" CellPadding="3" 
        DataSourceID="SqlDataSource1" ForeColor="Black" GridLines="Vertical" >
        <AlternatingRowStyle BackColor="#CCCCCC" />
        <Columns>
            <asp:BoundField DataField="Name" HeaderText="Name" />
            <asp:BoundField DataField="Team" HeaderText="Team" SortExpression="Team" />
            <asp:BoundField DataField="Matches" HeaderText="Matches" 
                SortExpression="Matches" />
            <asp:BoundField DataField="Points" HeaderText="Points" 
                SortExpression="Points" />
            <asp:BoundField DataField="Tries" HeaderText="Tries" SortExpression="Tries" />
            <asp:BoundField DataField="Conversions" HeaderText="Conversions" 
                SortExpression="Conversions"  />
            <asp:BoundField DataField="Penalties" HeaderText="Penalties" 
                SortExpression="Penalties" />
            <asp:BoundField DataField="Drop Goals" HeaderText="Drop Goals" 
                SortExpression="Drop Goals" />
            <asp:BoundField DataField="Yellow Cards" HeaderText="Yellow Cards" 
                SortExpression="Yellow Cards" />
            <asp:BoundField DataField="Red Cards" HeaderText="Red Cards" 
                SortExpression="Red Cards" />
        </Columns>
        <FooterStyle BackColor="#CCCCCC" />
        <HeaderStyle BackColor="Black" Font-Bold="True" ForeColor="White" />
        <PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
        <SelectedRowStyle BackColor="#000099" Font-Bold="True" ForeColor="White" />
        <SortedAscendingCellStyle BackColor="#F1F1F1" />
        <SortedAscendingHeaderStyle BackColor="#808080" />
        <SortedDescendingCellStyle BackColor="#CAC9C9" />
        <SortedDescendingHeaderStyle BackColor="#383838" />
    </asp:GridView>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
        ConnectionString="<%$ ConnectionStrings:ConnectionString %>" 
        SelectCommand="SELECT * FROM [statstable]"></asp:SqlDataSource> 
David Van Staden
  • 1,739
  • 9
  • 34
  • 52
  • Look here. http://stackoverflow.com/questions/702600/sorting-and-paging-with-gridview-asp-net, http://msdn.microsoft.com/en-us/library/hwf94875.aspx, http://www.netomatix.com/development/GridViewSorting.aspx – Jamie Oct 05 '11 at 19:07

6 Answers6

17
public partial class _Default : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Set your deault sort expression and direction.
        if (String.IsNullOrEmpty(MyGridView.SortExpression)) MyGridView.Sort("SortExpression", SortDirection.Ascending);
    }
}
skinnysoftware
  • 889
  • 1
  • 9
  • 14
  • I had a problem where the first click on the column header to sort by the column would not change the sort direction. Turns out that when a ListView is first created the sorting select method get a empty sort expression. The above will fix this problem. – Eric Vasilik Sep 28 '14 at 18:36
3

Why easy when it can be complicated, eh guys?

protected void GridView1_OnSorting(object sender, GridViewSortEventArgs e)
{
    // If you want to only switch default for some column, disable comment
    //switch (e.SortExpression)
    //{
    //    case "MyDataField01":
    //    case "MyDataField03":
            if (e.SortExpression != ((GridView)sender).SortExpression)
            {
                e.SortDirection = SortDirection.Descending;
            }
    //        break;
    //    default:
    //        break;
    //}
}

Of course, tie OnSorting event on GridView in aspx. Source: http://csc-technicalnotes.blogspot.com/2010/06/change-gridview-sortdirection-default.html

nikib3ro
  • 20,366
  • 24
  • 120
  • 181
0

I was googling around because I had the same question and was playing around and found that if I added "ORDER BY [Field Name]" in my SQL statement and enabled sorting, whenever I clicked on the header, it would reverse the order of any of the columns! I see this is a very old thread, but maybe it will help in the future for somebody else also. As a more in depth answer, here is my code for my datasource:

<asp:AccessDataSource ID="AccessDataSource1" runat="server" 
    DataFile="~/App_Data/webvideos.mdb" 
    DeleteCommand="DELETE FROM [Docs] WHERE [ID] = ?" 
    InsertCommand="INSERT INTO [Docs] ([ID], [Filename], [Label], [Section], [Index]) VALUES (?, ?, ?, ?, ?)" 
    SelectCommand="SELECT * FROM [Docs] ORDER BY ID" 
    UpdateCommand="UPDATE [Docs] SET [Filename] = ?, [Label] = ?, [Section] = ?, [Index] = ? WHERE [ID] = ?">

And here's my gridview:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="ID" DataSourceID="AccessDataSource1" AllowPaging="True" 
        PageSize="20" AllowSorting="True">
        <Columns>
            <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
            <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" 
                ReadOnly="True" SortExpression="ID" />
            <asp:BoundField DataField="Label" HeaderText="Label" SortExpression="Label" />
            <asp:BoundField DataField="Filename" HeaderText="Filename" 
                SortExpression="Filename" />
            <asp:BoundField DataField="Section" HeaderText="Section" 
                SortExpression="Section" />
            <asp:BoundField DataField="Index" HeaderText="Index" SortExpression="Index" />
        </Columns>
    </asp:GridView>
Joseph
  • 609
  • 2
  • 12
  • 26
0

I would recommend that you look at this post and reverse the ascending / descending flag logic.

GridView sorting: SortDirection always Ascending

Your ASPX page will have a gridview like this (pay specific attention to the OnSorting part):

<asp:GridView ID="grdHeader" AllowSorting="true" AllowPaging="false" 
   AutoGenerateColumns="false" Width="780" runat="server" 
   OnSorting="grdHeader_OnSorting" EnableViewState="true">
   <Columns>         
      <asp:BoundField DataField="Entitycode" HeaderText="Entity" SortExpression="Entitycode" />        
      <asp:BoundField DataField="Statusname" HeaderText="Status" SortExpression="Statusname" />         
      <asp:BoundField DataField="Username" HeaderText="User" SortExpression="Username" />     
   </Columns> 
 </asp:GridView> 

Your CodeBehind (aspx.cs) will then need to implement the method grdHeader_OnSorting. The variables in GridViewSortEventArgs will tell you which direction the user asked to sort. In your case you would then do the opposite...such as:

protected void grdHeader_OnSorting(object sender, GridViewSortEventArgs e)        
{               
   List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
   SortDirection dir = e.SortDirection == SortDirection.Ascending ? SortDirection.Descending : SortDirection.Ascending;
   items.Sort(new Helpers.GenericComparer<V_ReportPeriodStatusEntity>(e.SortExpression, dir));
   grdHeader.DataSource = items;     
   grdHeader.DataBind(); 
} 

Here the items.Sort method is doing all the sorting...all you are doing is taking that sorted result and assigning it back to your datasource.

If you want more information on the concept of how to sort a GridView, I'd recommend looking at this example on MSDN: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.sort.aspx

Let me know if there is anything else I can do to clarify.

Community
  • 1
  • 1
Joe Mancuso
  • 2,099
  • 1
  • 16
  • 17
  • You see my problem is the following. I did read through that post before I posted this, but there are 6 or 7 answer, all voted up on and differs from each other. I'm still very new to programming and ASP.NET and I don't really understand all that code. I can't believe that something that is suppose to be so simple is so complicated(complicated being used out of my expertise vocabulary)...Any more specific suggestions...Ive literally spend the whole day trying to solve this problem, but everywhere I go people's code differs significantly from each other. One says this, another says that. – David Van Staden Oct 05 '11 at 19:26
  • David, see my additions above – Joe Mancuso Oct 06 '11 at 00:56
  • yes thank you. I implemented it like you recommended, but I get the 'missing using directive or assembly reference' error for the following lines: V_ReportPeriodStatusEntity; GetPeriodStatusesForScreenSelection(); Helpers.Any suggestions? – David Van Staden Oct 06 '11 at 11:23
  • The V_ReportPeriodStatusEntity is just an example class...you need to put in the class that represents your model (your data). GetPeriodStatusesForScreenSelection() is just an example method that retrieves your model. Let's say that you want to show a table from a SQL database. You could use LinqToSQL to query that table. The query would be the GetPeriod..() method and the table row object would be the V_ member. For more on LinqToSql look at http://www.thereforesystems.com/linq-to-sql-tutorial/ – Joe Mancuso Oct 06 '11 at 12:20
  • Thanks, will take a look. Please see a solution to my question I found on another forum – David Van Staden Oct 06 '11 at 14:05
  • Your solution below is similar; it stores the value of the sort direction in the ViewState. The only issue is that it doesn't take the field being sorted into account. You could click on one field and it would sort descending, then click on another and it would sort it ascending. The above solution does take the field into account and performs similarly. – Joe Mancuso Oct 06 '11 at 14:18
0

I am afraid that's the default behavior, if you want to change it, you have to implement the OnSorting event on the GridView and switch the behavior based on the sort expression. For example, if the sort expresion is TEAM DESC then you would sort TEAM ASC and viceversa.

Something like this (assuming your SelectCommand is a simple select statement without an order by clause):

 protected void GridView1_Sorting(Object sender, GridViewSortEventArgs e)
  {
    string originalSelectCommand = SqlDataSource1.SelectCommand;
    if (e.SortDirection == "ASC")//sort data source in DESC
    {
       if(e.SortExpression=="Team")
       {
           SqlDataSource1.SelectCommand=SqlDataSource1.SelectCommand + " Order BY TEAM DESC";               
       }
       else if(e.SortExpression=="Another Column") //etc
       {
       }
    }
    else //Sort data source in ASC
    {
    }
    SqlDataSource1.Select(DataSourceSelectArguments.Empty);
    GridView1.DataBind();
    SqlDataSource1.SelectCommand=originalSelectCommand;//revert back to original w/o order by
  }

All you need to do to your markup is:

    <asp:GridView ID="GridView1" runat="server"  
    OnSorting="GridView1_Sorting"
    AllowSorting="True" 
    AutoGenerateColumns="False" BackColor="White" BorderColor="#999999" 
    BorderStyle="Solid" BorderWidth="1px" CellPadding="3" 
    DataSourceID="SqlDataSource1" ForeColor="Black" GridLines="Vertical" >
    <AlternatingRowStyle BackColor="#CCCCCC" />

Warning: Above code was not tested at all but I think it should do what you want.

Icarus
  • 63,293
  • 14
  • 100
  • 115
  • Thanks for the reply. Visual Studio underlines the statment if (e.SortDirection == "ASC") in red and says: Operator == cannot be applied to operands of type 'Sytem.Web.UI.Webcontrols.SortDirection' and 'String'. Please keep in mind I have very little knowledge about asp.net functions and coding, please try to keep it as simple and explanatory as possible. Everyone assumes I know exactly what they are talking about and that I understand the code. If I did, I would be asking the question – David Van Staden Oct 06 '11 at 08:40
0

I found a solution on another forum, but it still has flaws-What I wanted was the default first click sorting order on a column to be descending, and not ascending. But when I click on another column again, it sets the sort direction to ascending again. It alternates between descending and ascending on every click, no matter which column. Now what I really want is for the first click on any column to be descending, and if I click any column for the second time, it should be ascending. Example: I have 2 columns, one is salary and the other is age. Now I click on salary, and the first sorting direction is descending, not the default ascending(that's what the code does).Now when I click on age, it switches the sorting direction to ascending, I want it to stay the same when I change to another column, BUT should I click on salary again for the second time, it should switch to ascending(cause descending was the first click). Any suggestions?

The Code: `

public SortDirection GridViewSortDirection
{
    get
    {
        if (ViewState["sortDirection"] == null) //if viewstate doesn't contain any value, assume SortDirection.Ascending(cause thats the asp default)
            ViewState["sortDirection"] = SortDirection.Ascending;
        return (SortDirection)ViewState["sortDirection"];
    }
    set
    {
        ViewState["sortDirection"] = value;  //Viewstate sort direction is set as a variable, so can contain either asc or desc
    }
}
protected void GridView1_OnSorting(object sender, GridViewSortEventArgs e)
{
    if (ViewState["sortDirection"] == null)
    {
        e.SortDirection = SortDirection.Descending;
    }
    else if (GridViewSortDirection == SortDirection.Ascending)
    {
        e.SortDirection = SortDirection.Descending;
    }
    else if (GridViewSortDirection == SortDirection.Descending)
    {
        e.SortDirection = SortDirection.Ascending;
    }

    GridViewSortDirection = e.SortDirection;
}

`

David Van Staden
  • 1,739
  • 9
  • 34
  • 52