With everything else being equal, a BoundField column in an asp:GridView is sortable, but a TemplateField column is not. Why is that?
<asp:LinqDataSource ID="someDataSource" runat="server"
ContextTypeName="someDataContext" TableName="someTable"
OnSelecting="someSelectingHandler" />
<asp:GridView ID="somGrid" runat="server"
AllowPaging="true" AllowSorting="true"
EnableSortingAndPagingCallbacks="true" PageSize="15"
DataSourceID="someDataSource" EnableViewState="true"
EmptyDataText="No orders matched your criteria">
<Columns>
<!-- resulting column is sortable: -->
<asp:BoundField HeaderText="Order #" HtmlEncode="false"
DataField="order_number" SortExpression="order_number">
</asp:BoundField>
<!-- resulting column is not sortable: -->
<asp:TemplateField SortExpression="order_number">
<HeaderTemplate>Order #</HeaderTemplate>
<ItemTemplate><%# DataBinder.Eval(Container.DataItem,
"order_number")%></ItemTemplate>
</asp:TemplateField>
Clicking on the BoundField header results in a post-back and my Selecting event handler is called. It just returns an IQueryable and itself does not handle sorting. The documentation merely says that the "underlying data source must support sorting" in order for the GridView to be sortable. Apparently the LinqDataSource supports sorting, or else the BoundField would not be sortable. Or am I missing something?
So I asked the wrong question. It turns out the GridView is actually sortable, even when TemplateField columns are used. The TemplateField does not support the EncodeHtml attribute that is available with the BoundField tag. This means that it is not possible to force line breaks in TemplateField headers with the HeaderText attribute. Using a HeaderTemplate is the solution for that, but by just using static text, the column is no longer sortable.
This link has the solution.