1

I have a gridview that I would like to have sortable. When I define it like this:

<asp:GridView ID="GridView1" runat="server" CssClass="gridview" DataSourceID="GridDataSource" AutoGenerateColumns="False" AllowSorting="True" >

The sorting works just fine. ie. when I click the column header the grid sorts by that column.

But when I define it like this:

<asp:GridView ID="GridView1" runat="server" CssClass="gridview"  AutoGenerateColumns="False" AllowSorting="True" >

and in codebehind:

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

Using the latter method the sorting does not work. The column headers are links but the grid does not order itself.

I'm setting the DataSource after the page load so the user can chose from some filters (dropdown lists) to restrict the records returned.

Can someone tell me how to set the datasource in codebehind and get sorting functioning? Alternatively a good way to stop the grid from databinding on initial page load.

  • 2
    You might find your answer in [this SO post](http://stackoverflow.com/questions/5388245/gridview-sorting-works-once-only) – Michael Oct 10 '14 at 12:22

1 Answers1

1

To get automatic sorting on an you'll need a few things.

First, you'll have to set AllowSorting="True" on the gridview tag, which you did.

Second, you'll need to configure your Fields correctly. Since you have AutoGenerateColumns=false you'll need to manually specify the SortExpression:

<asp:BoundFiled DataFiled="Name" HeaderText="Name" SortExpression="Name" />

Third, you'll need to make sure your data source supports sorting. If you data bind directly to a DataSet you should get support out of box. However, if you are binding to a or you'll need to ensure that your SelectMethod supports sorting.

For example, for an you'll need to set the SortParameterName and then ensure that same parameter is present in the SelectParameters collection:

 <asp:ObjectDataSource ID="GridDataSource" runat="server"
    SelectMethod="ExampleSelect"
    TypeName="SO"        
    SortParameterName="sortExpression">       
    <SelectParameters>
        <asp:Parameter Name="sortExpression" Type="String" />
    </SelectParameters>
 </asp:ObjectDataSource>

Then the SelectMethod will be responsible for implementing the sorting:

 namesapce SO{
     public class ExampleSelect{
         public object[] ExampleSelect(string sortExpression)
         {
            var allItems = GetAllItems();

            bool sortDesc = 
                 //if sort descending, sortExpression will be suffixed with " DESC"
                 (sortExpression.Split(' ').Count() > 1);

            if (sortExpression.StartsWith("Name"))
            {
                if (sortDesc)
                    return allItems.OrderByDescending(x => x.Name);
                else
                    return allItems.OrderBy(x => x.Name);
            }
            else
            {
               return allItems;
            }
         }
     }
 }

Tips

Databinding in code_behind

I recommend data binding declaratively in markup using one of the datasource controls. It gets rid of misc code in the code behind and lets the framework deal with when to databind so you don't have to bust out the if (!IsPostBack) statements.

Community
  • 1
  • 1
Philip Pittle
  • 10,003
  • 7
  • 47
  • 100
  • I tried this but the datasource function is not called when I click to order the grid - so the "sortExpression" doesn't do anything. I'm sure you are correct in everything you said but I'm definitely missing something. – Ivar Ragnarsson Oct 10 '14 at 16:36
  • Can you update the question with your select method and your object data source declaration – Philip Pittle Oct 10 '14 at 16:38
  • I've been tidying the code massively and as a result this now works using your solution. – Ivar Ragnarsson Oct 13 '14 at 11:11
  • 1
    I have a datasoure called "GridDataSource" and after backtracking a little bit I realized that I had changed one line from `GridView1.DataSource = GridDataSource;` TO `GridView1.DataSourceID = "GridDataSource";` That seems to make all the difference. – Ivar Ragnarsson Oct 13 '14 at 11:38
  • Yes, that will do it! Setting `DataSourceID` tells the GridView to use a specific control. Setting `DataSource` to "GridDataSource" will bind your GridView to a string. – Philip Pittle Oct 13 '14 at 12:16