I can't get my GridView to enable a user to sort a column of data when I'm using a custom SqlDataSource.
I have a GridView in which the code in the ASP reference to it in the HTML is minimal:
<asp:GridView id="grid" runat="server" AutoGenerateColumns="False" AllowSorting="True">
</asp:GridView>
In the code-behind I attach a dynamically-created SqlDataSource (the columns it contains are not always the same so the SQL used to create it is constructed at runtime). For example:
I set up the columns...
BoundField column = new BoundField();
column.DataField = columnName;
column.HeaderText = "Heading";
column.SortExpression = columnName;
grid.Columns.Add(column);
the data source...
SqlDataSource dataSource = new SqlDataSource(
"System.Data.SqlClient",
connectionString,
generatedSelectCommand);
then the gridview...
grid.DataSource = dataSource;
grid.DataKeyNames = mylistOfKeys;
grid.DataBind();
At the moment nothing happens when a user clicks on a column heading when I'd expect it to sort the column data. Anyone any ideas what I'm missing?
If there's a nicer way of doing this that would be helpful too as this looks messy to me!
I'm not sure about this one, but if you use a standard SqlDataSource and you click on a field to sort according to that field, the SqlDataSource is populated again with the data and it is rebound to the grid. So the sorting does not happen on the client side and also can be done only when the selectmethod of the SQLDataSource is not DataReader.
When handling the sorting event, do you recreate the SqlDataSource and rebound it to the GridView? Can you put the sort field and direction to the generatedSelectCommand, which you use? Or put it to the SortParameterName property of the SQLDataSource?
I'm absolutely sure that you have to rebound the SqlDataSource to the grid, and since you create it on the fly, you have to populate it again.
First you need to add an event:
Then that event looks like:
You basically have to get your data again.
You're right that it looks messy and there is a better way: ASP.Net MVC
Unfortunately that's a drastically different page model.
You could also just reassign the datasource.SelectCommand before the DataBind() call in the Sorting handler. Something like this:
I hope this help. Let me know if you need extra help to implement it.
Enjoy!
Better late than never?
Some addition for Keith's suggestion which is basically the right one.
Truth is, that you have to deal with sorting on gridView_Sorting event. There is no need to DataBind() the GridView earlier, for example in Page_Load event. There you should only call the GridView.Sort() method instead of .DataBind(). Here is how it goes:
Next let's have a look on gridView_Sorting event.
There you have to push the datasource to the right sorting. GridView itself does not handle that (in this case at least).
No need to code any sorting functionality in data source like passing sort parameters to stored procedure. All sorting takes place in the above pieces of code.
Moreover, it's good to have the gridView.EnableViewState switched to False which causes the page to be much lighter for the network traffic and for the browser as well. Can do that as the grid is entirely recreated whenever the page is post back.
Have a nice day!
Martin