ListView and GridView can already sort the data but this functionality works with post back and the generate links are javascript functions and not SEO friendly links.

The only SEO friendly functionality connected to these controls is the pagination made with the DataPager but alas only with the ListView because the GridView doesn't implement the necessary interface IPageableItemContainer.

SEO friendly pagination using asp:DataPager control

The GridView can be enhanced to implement the IPageableItemContainer.

Using a DataPager with the GridView Control - Implementing IPageableItemContainer

The SorterHyperLink follows the same path and it generates SEO friendly links to sort the ListView and GridView.

The ListView and GridView have the same method and properties to control the sorting functionality but there isn't an interface for them.

The first step is adding an interface to cover the sorting method and properties:

public interface ISortableItemContainer
    string SortExpression { get; }
    SortDirection SortDirection { get; }
    void Sort(string expression, SortDirection direction);

Then add an adapter to use the new interface with the ListView and GridView without have to extend them:

public static ISortableItemContainer GetAdapter(Control control)
    ISortableItemContainer ret = null;

    var type = control.GetType();
    var type1 = typeof(string);
    var type2 = typeof(SortDirection);
    MethodInfo mi = type.GetMethod("Sort", new Type[] { type1, type2 });
    PropertyInfo pi1 = type.GetProperty("SortExpression", type1);
    PropertyInfo pi2 = type.GetProperty("SortDirection", type2);

    if (mi != null && pi1 != null && pi2 != null)
        ret = new SortableItemContainerAdapter(control, mi, pi1, pi2);

    return ret;

The SorterHyperLink uses this interface or the adapter to find the GridView or ListView.

Control container = this;
ISortableItemContainer isic = null;
while (container != null && isic == null)
    container = container.NamingContainer;
    isic = container as ISortableItemContainer ?? SortableItemContainerAdapter.GetAdapter(container);

The SorterHyperLink control works well in conjunction with the DataPager but not with the embedded paging function of the GridView. In the case that the GridView is extended to implement the IPageableItemContainer, it can be added also the ISortableItemContainer interface, which is already implemented from the GridView and also from the ListView.

public class ListViewEx : ListView, ISortableItemContainer { }

The SorterHyperLink can be used as header of the columns, here for example in the ListView


<table ID="itemPlaceholderContainer" runat="server" border="0" rules="all" style="border:1px solid black">
    <tr id="Tr2" runat="server">
        <th id="Th1" runat="server">
            <cc1:SorterHyperLink runat="server" Text="Title" Expression="Title" QueryStringField="Sort1" />
        <th id="Th2" runat="server">
            <cc1:SorterHyperLink runat="server" Text="FirstName" Expression="FirstName" QueryStringField="Sort1" />
        <th id="Th3" runat="server">
            <cc1:SorterHyperLink runat="server" Text="LastName" Expression="LastName" QueryStringField="Sort1" />
    <tr ID="itemPlaceholder" runat="server">

In the GridView, before using the SorterHyperLink, the columns have to be converted in a TemplateField

After that the TemplateField can be extended with the SorterHyperLink

<asp:TemplateField HeaderText="Title" SortExpression="Title">
        <cc1:SorterHyperLink runat="server" ID="SorterHyperLink1" Text="Title" Expression="Title" QueryStringField="Sort3" />
        <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Title") %>'></asp:TextBox>
        <asp:Label ID="Label1" runat="server" Text='<%# Bind("Title") %>'></asp:Label>

Last edited Feb 3, 2013 at 2:29 PM by Aquilax, version 7