This is an example of what we use. Very similar to what Jan is explaining but with a few more tweaks.
In the transformation we use this method to get the sort direction to append to the header link:
<script runat="server">
public string GetSortDirection()
{
string sort = ValidationHelper.GetString(HttpUtility.UrlDecode(Request.QueryString["sort"]), "");
string[] sortString = sort.Split(' ');
string sortDir = "asc";
if (sortString.Length >= 2)
{
sortDir = sortString[1];
if(sortDir.ToLower().Equals("asc"))
{
sortDir = "desc";
}
else
{
sortDir = "asc";
}
}
return sortDir;
}
</script>
Then in the actual transformation we add a placeholder so we can dynamically generate the opening table tag and the header row.
<asp:PlaceHolder ID="ph1" runat="server" Visible='<%# IsFirst() %>'>
<div class="unigrid-content">
<table class="table">
<thead>
<tr class="unigrid-head">
<th><a href="<%# CurrentDocument.NodeAliasPath %>?searchtext=<%# Request.QueryString["searchtext"] %>&searchmode=<%# Request.QueryString["searchmode"] %>&sort=<%# "FileName+" + GetSortDirection() %>">Name </a></th>
<th><a href="<%# CurrentDocument.NodeAliasPath %>?searchtext=<%# Request.QueryString["searchtext"] %>&searchmode=<%# Request.QueryString["searchmode"] %>&sort=<%# "FileDate+" + GetSortDirection() %>">Date </a></th>
<th><a href="<%# CurrentDocument.NodeAliasPath %>?searchtext=<%# Request.QueryString["searchtext"] %>&searchmode=<%# Request.QueryString["searchmode"] %>&sort=<%# "Attachement_1+" + GetSortDirection() %>">Attachment</a></th>
</tr>
</thead>
<tbody>
</asp:PlaceHolder>
Now we have the standard item text (or table row in our case):
<tr>
<td><a href='<%# GetAbsoluteUrl("/getattachment/" + Eval("FileAttachment")) %>' title="Download" target="_blank"> <%# GetSearchValue("FileName") %></a></td>
<td><%# FormatDateTime(Eval("FileDate"), "MM/dd/yyyy") %></td>
<td><a href="<%# GetAbsoluteUrl("/getattachment/" + Eval("Attachment_1")) %>">
▼<%# Eval("Attachment1Name") %>
</a></td>
</tr>
Lastly, we close out the opening div and table tags using a similar approach with the placeholder.
<asp:PlaceHolder ID="ph2" runat="server" Visible='<%# IsLast() %>'>
</tbody>
</table>
</div>
</asp:PlaceHolder>
Now for the configuration of the Search sort property in the webpart. We use this macro to get the "sort" querystring parameter.
`{% if(QueryString.GetValue("sort") == ""){"FileName ASC"}else{UrlDecode(QueryString.GetValue("sort"))} @%}`
Of course you will have to make modifications to your field names but for the most part this solution should work just fine.