0

I have an exisiting gridview that I need to fix/improve here at work. Basically the GridView has headings and they are being binded by a data set in the code behind, it uses BoundFields and TemplateFields. The problem is that I am needed to make each column sortible. What would be the best approach to do this since it is not the standard gridview?, I need to make the header links and when click to sort in DESC or ASC order. Here is an example of the gridview I need to work on.

<asp:GridView ID="theGrid" runat="server" CssClass="Grid" AllowPaging="True" AutoGenerateColumns="False" CellPadding="4" ForeColor="#FFFFFF" GridLines="None" OnPageIndexChanging="theGrid_PageIndexChanging" CaptionAlign="Left" OnRowCommand="theGrid_RowCommand" Width="100%" PageSize="25" AllowSorting="True" EmptyDataText="It's Empty.">
    <Columns>
        <asp:BoundField DataField="TestID" HeaderText="ID"/>
        <asp:TemplateField HeaderText="Name">
            <ItemTemplate>
                <a href='sometest.aspx?ID=<%# DataBinder.Eval(Container.DataItem, "TestID").ToString()%>'><%# DataBinder.Eval(Container.DataItem, "Type").ToString()%></a>
            </ItemTemplate> 
        </asp:TemplateField>    
          <asp:TemplateField HeaderText="Address">
            <ItemTemplate>
                <div align="right"><%# (DataBinder.Eval(Container.DataItem, "HouseNumber"))%></div>
            </ItemTemplate> 
        </asp:TemplateField>  

...etc, What would be the best way to sort BoundFields and TemplateFields?

1
  • For instance how can I sort by ID? given the example above and enable the link?, right now it just shows the header "not clickable" Commented Jul 6, 2011 at 19:49

1 Answer 1

2

You need to set the SortExpression.

<asp:TemplateField HeaderText="Name" SortExpression="Name">
    <ItemTemplate>
        <a href='sometest.aspx?ID=<%# DataBinder.Eval(Container.DataItem, "TestID").ToString()%>'><%# DataBinder.Eval(Container.DataItem, "Type").ToString()%></a>
    </ItemTemplate> 
</asp:TemplateField>    
<asp:TemplateField HeaderText="Address" SortExpression="Address">
    <ItemTemplate>
                <div align="right"><%# (DataBinder.Eval(Container.DataItem, "HouseNumber"))%></div>
    </ItemTemplate> 
</asp:TemplateField>            

in the codebehind you can store the current SortExpression and the SortDirection in ViewState:

Private Property SortExpression() As String
    Get
        If ViewState("SortExpression") Is Nothing OrElse ViewState("SortExpression").ToString().Length = 0  Then
            ViewState("SortExpression") = "Name ASC"
        End If
        Return ViewState("SortExpression").ToString
    End Get
    Set(ByVal value As String)
        ViewState("SortExpression") = value
    End Set
End Property

and in the Sorting-Handler of the GridView:

Protected Sub theGrid_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles theGrid.Sorting
    Dim currentSortColumn, currentSortDirection As String
    currentSortColumn = Me.SortExpression.Split(" "c)(0)
    currentSortDirection = Me.SortExpression.Split(" "c)(1)

    If e.SortExpression.Equals(currentSortColumn) Then
        'switch sort direction
        Select Case currentSortDirection.ToUpper
            Case "ASC"
                Me.SortExpression = currentSortColumn & " DESC"
            Case "DESC"
                Me.SortExpression = currentSortColumn & " ASC"
        End Select
    Else
        Me.SortExpression = e.SortExpression & " ASC"
    End If

    BindGrid() 'load the data with this SortExpression and DataBind the Grid'
End Sub

Sorry for VB.NET, i've noticed too late. You could translate it here.

Edit: C#

private string SortExpression {
    get {
        if (ViewState("SortExpression") == null || ViewState("SortExpression").ToString().Length == 0) {
            ViewState("SortExpression") = "Name ASC";
        }
        return ViewState("SortExpression").ToString;
    }
    set { ViewState("SortExpression") = value; }
}



protected void theGrid_Sorting(object sender, System.Web.UI.WebControls.GridViewSortEventArgs e)
{
    string currentSortColumn = null;
    string currentSortDirection = null;
    currentSortColumn = this.SortExpression.Split(' ')[0];
    currentSortDirection = this.SortExpression.Split(' ')[1];

    if (e.SortExpression.Equals(currentSortColumn)) {
        //switch sort direction
        switch (currentSortDirection.ToUpper()) {
            case "ASC":
                this.SortExpression = currentSortColumn + " DESC";
                break;
            case "DESC":
                this.SortExpression = currentSortColumn + " ASC";
                break;
        }
    } else {
        this.SortExpression = e.SortExpression + " ASC";
    }

    //load the data with this SortExpression and DataBind the Grid
    BindGrid();
}
Sign up to request clarification or add additional context in comments.

5 Comments

@user: i've changed a little bit. I'd used a helper function GetString(ViewState("SortExpression") in the old code what wasn't in this sample. Now it should compile ;)
Hello Just a little question, I have method to do the BindGrid(); what do I need to load the data with the SortExpression?, or I just call BindGrid() and it should take care of it?
@user: that depends on how and from where you are loading the data. But in simple terms the property SortExpression is the ORDER BY of your SELECT. By the way, BindGrid is not a .NET function but that one in which you are loading the DataSource of the GridView and call theGrid.DataSource = yourDataSource and theGrid.DataBind.
Got it and one last question, if I have a BoundField like this <asp:BoundField DataField="AddressID" HeaderText="ID" SortExpression=""/> whatshould be the SortExpresion the Header or the DataField?
@User: Do you really want to show the user the primary-key or is it only to identify your records? Then you could make this column invisible. If you want to show it and and make it sortable, you also have to set the BoundField's SortExpression to the column name. That applies also to the TemplateFields, the headerText is irrelevant.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.