Gridview sorting with custom template fields

Mark picture Mark · Oct 21, 2009 · Viewed 28.3k times · Source

I can't seem to figure out how to sort my gridview with both databound AND custom fields.

The custom field look like this:

  <asp:Label ID="lblItems" runat="server" Text='<%# GetItems((int)DataBinder.Eval(Container.DataItem, "ObjectCategoryID"))%>' />

It calls for a function which shows how many item the given category has.

The sorting for the databounded fields work perfec but not the customfields. Im also looking for a generic method which works for all my gridviews.

Can someone help me in the right direction please? Below is my full customgrid code.

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

using System.Xml.Linq;
using System.Collections;

namespace CustomControls
{
    public class CustomGrid : GridView
    {
        public CustomGrid()
        {
              PageIndexChanging += CustomGrid_PageIndexChanging;
        }        

    private string ConvertSortDirectionToSql(SortDirection sortDirection)
    {
        string newSortDirection = String.Empty;

        switch (sortDirection)
        {
            case SortDirection.Ascending:
                newSortDirection = "ASC";
                break;

            case SortDirection.Descending:
                newSortDirection = "DESC";
                break;
        }

        return newSortDirection;
    }  

    protected void CustomGrid_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        this.PageIndex = e.NewPageIndex;
        this.DataBind();
    }

    protected override void OnSorting(GridViewSortEventArgs e)
    {
        DataSet ds = (DataSet)System.Web.HttpContext.Current.Session["Source"];
        DataTable dataTable = ds.Tables[0];

        if (dataTable != null)
        {
            DataView dataView = new DataView(dataTable);


            if ((string)System.Web.HttpContext.Current.Session["Direction"] == "Asc")
            {
                dataView.Sort = e.SortExpression + " " + "ASC";
                System.Web.HttpContext.Current.Session["Direction"] = "Desc";
            }

            else if ((string)System.Web.HttpContext.Current.Session["Direction"] == "Desc")
            {
                dataView.Sort = e.SortExpression + " " + "DESC";
                System.Web.HttpContext.Current.Session["Direction"] = "Asc";
            }

            else
            {
                dataView.Sort = e.SortExpression + " " + "ASC";
                System.Web.HttpContext.Current.Session["Direction"] = "Desc";
            }

            this.DataSource = dataView;
            this.DataBind();
        }
    }

    protected override void OnInit(System.EventArgs e)
    {
        this.AllowSorting = true;
        this.AllowPaging = true;
        this.PagerSettings.Mode = PagerButtons.NumericFirstLast;
        this.AutoGenerateColumns = false;
        this.CssClass = "gv";
        this.RowStyle.CssClass = "gvRow";
        this.AlternatingRowStyle.CssClass = "gvAlternateRow";
        this.HeaderStyle.CssClass = "gvHeader";
        this.GridLines = GridLines.None;
        this.PagerStyle.CssClass = "gvPager";
        this.EmptyDataText = "<div style=\"width:100%;text-align:left;\">No data found</div>";
    }
}

Answer

Martin picture Martin · Feb 13, 2012

I had the same issue, the BoundField was sorting as it should, but the TemplateField did not sort at all.

I changed this:

<asp:TemplateField SortExpression="Category">
   <HeaderTemplate>Category</HeaderTemplate>
   <ItemTemplate>A value</ItemTemplate>
</asp:TemplateField>

To this:

<asp:TemplateField HeaderText="Category" SortExpression="Category">
   <ItemTemplate>A value</ItemTemplate>
</asp:TemplateField>

I removed the HeaderTemplate and added the HeaderText in the TemplateField.