Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Sort on a GridView using ObjectDataSource with TemplateFields

Background:

I am working with a GridView and an ObjectDataSource. I am implementing Paging and Sorting.

On the ObjectDataSource:

        objectDataSource.TypeName = value;
        objectDataSource.SelectMethod = "Select";
        objectDataSource.SelectCountMethod = "SelectCount";
        objectDataSource.SortParameterName = "sortExpression";
        objectDataSource.EnablePaging = true;

On the GridView:

        gridView.AllowPaging = true;
        gridView.AllowSorting = true;
        gridView.DataSource = objectDataSource;

To get paging and sorting to work, I set "EnableSortingAndPagingCallbacks" to True. Before, I was getting a "System.Web.HttpException: The GridView fired event Sorting which wasn't handled." and this fixes it.

If I use only BoundFields in my GridView, this is great and works fine.

However, if I used TemplateFields, I get a "NotSupportedException: Callbacks are not supported on TemplateField because some controls cannot update properly in a callback. Turn callbacks off on GridView."

Which, makes sense. I just need to know how to make sorting work, without using EnableSortingAndPagingCallbacks.

If EnableSortingAndPagingCallbacks = True:

  • Paging Works
  • Sorting Works
  • BoundFields Work
  • TemplateFields do Not Work

If EnableSortingAndPagingCallbacks = False:

  • Paging Works
  • Sorting does Not Work
  • BoundFields Work
  • TemplateFields Work

My Question:

How do I go about getting Paging, Sorting, and TemplateFields to work, all at the same time?


Clarification on the implementation:

Using an ObjectDataSource with a GridView requires implementing a method called Select that provides a sort expression, the number of rows to return, and the start row:

    public IEnumerable<CountyAndStateGridRow> Select(string sortExpression, int maximumRows, int startRowIndex)
    {
        string oql = "select County order by {" + sortExpression + "}" ;

        var counties = QueryProvider.ExecuteQuery(oql).Cast<County>();

        var page = counties.Skip(startRowIndex).Take(maximumRows);

        var rows = page.Select(
            county => new CountyAndStateGridRow
            {
                CountyName = county.Name,
                StateName = county.State.Name,
            });

        return rows;
    }

The specific SortExpression is defined in the aspx/ascx:

<Columns>
       <asp:BoundField HeaderText="County Name" DataField="CountyName" SortExpression="Name" />
       <asp:BoundField HeaderText="State Name" DataField="StateName" SortExpression="State.Name" />
</Columns>

This is supposed to be passed in and call the Select method on the ObjectDataSource when the column is clicked, but it does not seem to work if EnableSortingAndPagingCallbacks = true, and instead I get the exception about the Sorting event not being defined.

like image 866
Jonathan Mitchem Avatar asked Jun 16 '09 15:06

Jonathan Mitchem


1 Answers

For sorting functionality to work:

 <asp:GridView GridView ID="GvCountryDetails" AllowPaging="True" 
OnPageIndexChanging="GvCountryDetails_PageIndexChanging" AllowSorting="True" 
onsorting="GvCountryDetails_Sorting">

in .cs file you need to write

protected void GvCountryDetails_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        GvCountryDetails.PageIndex = e.NewPageIndex;
        isPageIndexChanged = true;
        BindData();
    }

protected void GvCountryDetails_Sorting(object sender, GridViewSortEventArgs e)
    {
        sortExpression = e.SortExpression;
        isPageIndexChanged = false;
        BindData();
    }
    private void SortGridData()
    {
        string sSortdir;
        if (isPageIndexChanged == true)
        {
            sSortdir = ViewState["SortDirection"] as string;
        }
        else
        {
            sSortdir = GetSortDirection(sortExpression);
        }

        string sSortExp = sortExpression;

        if (sSortdir == "ASC")
        {
            lstCountryDetails = Sort<Country>(lstCountryDetails, sSortExp, SortDirection.Ascending);
        }
        else
        {
            lstCountryDetails = Sort<Country>(lstCountryDetails, sSortExp, SortDirection.Descending);
        }
    }

    private List<CountryBO> Sort<TKey>(List<CountryBO> list, string sortBy, SortDirection direction)
    {
        PropertyInfo property = list.GetType().GetGenericArguments()[0].GetProperty(sortBy);
        if (direction == SortDirection.Ascending)
        {
            return list.OrderBy(e => property.GetValue(e, null)).ToList<CountryBO>();
        }
        else
        {
            return list.OrderByDescending(e => property.GetValue(e, null)).ToList<Country>();
        }
    }

    private string GetSortDirection(string column)
    {
        string sortDirection = "ASC";
        string sortExpression = ViewState["SortExpression"] as string;
        if (sortExpression != null)
        {
            if (sortExpression == column)
            {
                string lastDirection = ViewState["SortDirection"] as string;
                if ((lastDirection != null) && (lastDirection == "ASC"))
                {
                    sortDirection = "DESC";
                }
            }
        }

        ViewState["SortDirection"] = sortDirection;
        ViewState["SortExpression"] = column;
        return sortDirection;
    }
like image 185
dh_tech Avatar answered Nov 06 '22 10:11

dh_tech