How to Sort on a GridView using ObjectDataSource with TemplateFields
Asked Answered
S

3

7

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.

Shrievalty answered 16/6, 2009 at 15:20 Comment(0)
H
1

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;
    }
Heaney answered 6/6, 2014 at 9:32 Comment(0)
F
0

The property EnableSortingAndPagingCallbacks tells the control to do a client side sort of the data, so that the control appears to automatically sort without a page postback. TemplateFields are not supported with this method. In order to use TemplateFields and perform sorting, you need to wire up the GridView.Sorting event, and set the AllowSorting property to true. Once that is done, the event should fire when the column header is clicked and the sorting logic can be handled from there.

Flowers answered 17/6, 2009 at 13:29 Comment(1)
The page does make a call to the server when EnableSortingAndPagingCallbacks is set to True. (I.e., it is not purely client side.) When I click on a sortable column, the Select method on the data source specified by ObjectDataSource is actually called with the Column name as the sortExpression parameter, which then is turned into a query with an "order by" in my code.Shrievalty
C
0

Change the SortExpression value with the value of DataField. Set AllowPaging and AllowSorting to true. Set EnableSortingAndPagingCallbacks to true.

Clementeclementi answered 25/7, 2014 at 14:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.