Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting a gridview when databinding a collection or list of objects

I have a GridView set up in the following way:

  • bound to a List<T> in code-behind (I am using my own custom BOL)
  • no DataSource Object on the HTML page
  • sortable on each column that I choose (the SortExpressions are all set correctly)

However, I am getting the following error message:

The GridView 'myGridView' fired event Sorting which wasn't handled.

What is the best way for me to get my List<T> to allow sorting?

I am suspecting that it will have to do with specifying a function for the OnSorting attribute, i.e.:

OnSorting = "MySortingMethod"
like image 838
p.campbell Avatar asked Mar 05 '09 23:03

p.campbell


4 Answers

Thank you for your answers on the sorting. I turned to LINQ to help sort dynamically. Since the grid knows whether to sort ASC or DESC, and which field, I used a LINQ Expression. The Expression performed the sorting, and then I simply bound those results to my gridview.

I suspect the jQuery method would be faster, and wouldn't require a full postback.

using System.Linq.Expressions;

public SortDirection GridViewSortDirection
{
    get
    {
        if (ViewState["sortDirection"] == null)
            ViewState["sortDirection"] = SortDirection.Ascending;

        return (SortDirection)ViewState["sortDirection"];
    }
    set { ViewState["sortDirection"] = value; }
}

protected void gridView_Sorting(object sender, GridViewSortEventArgs e)
{
    //re-run the query, use linq to sort the objects based on the arg.
    //perform a search using the constraints given 
    //you could have this saved in Session, rather than requerying your datastore
    List<T> myGridResults = PerfomSearch();


    if (myGridResults != null)
    {
        var param = Expression.Parameter(typeof(T), e.SortExpression);
        var sortExpression = Expression.Lambda<Func<T, object>>(Expression.Convert(Expression.Property(param, e.SortExpression), typeof(object)), param);


        if (GridViewSortDirection == SortDirection.Ascending)
        {
            myGridView.DataSource = myGridResults.AsQueryable<T>().OrderBy(sortExpression);
            GridViewSortDirection = SortDirection.Descending;
        }
        else
        {
            myGridView.DataSource = myGridResults.AsQueryable<T>().OrderByDescending(sortExpression);
            GridViewSortDirection = SortDirection.Ascending;
        };


        myGridView.DataBind();
    }
}
like image 64
p.campbell Avatar answered Oct 22 '22 01:10

p.campbell


Correct - you will need to handle the onsorting, sort your list and re-bind.

Alternatively you could look at handling the sorting client side using a javascript framework like jQuery.

like image 31
brendan Avatar answered Oct 22 '22 03:10

brendan


If you get this error:

the datasource does not support server side paging

Try adding .ToList<T>() to your query:

if (e.SortDirection == SortDirection.Ascending)
{
    GridViewTrackerLoans.DataSource = myGridResults.AsQueryable<T>().OrderBy(sortExpression).ToList<T>();
}
else
{
    GridViewTrackerLoans.DataSource = myGridResults.AsQueryable<T>().OrderByDescending(sortExpression).ToList<T>();
};
like image 21
Brandon Culley Avatar answered Oct 22 '22 03:10

Brandon Culley


You could write a Compare for your objects:

private int CompareObject(YourObject object1, YourObject object2)
{
    int iReturnValue = 0;
    if ((object1 != null) && (object2 != null) &&
        (object1.SomeField != object2.SomeField))
    {
        iReturnValue = (object1.SomeField > object2.SomeField) ? 1 : -1;
    }
    return iReturnValue;
}

Then when in your sorting event just pass in the Compare function into your objects sort routine (assuming you have something like List).

// Your list of data from the session or viewstate or whereever you have it stored.
lstObjects.Sort(CompareObject);

You now have a sorted list so just rebind it.

like image 30
Kelsey Avatar answered Oct 22 '22 01:10

Kelsey