Wednesday, October 11, 2006

GridView Sorting with the ObjectDataSource

In an attempt to move some of the data access and business objects out of the presentation layer of an inherited web application, I have started working with the ObjectDataSource and custom business objects. The other day when I was testing a grid, I kept hitting exceptions whenever I tried to sort the grid stating that the OnSorting event was not being properly overridden.

The reality was that the OnSorting was being overridden, but I was not canceling the sort event of the gridview. If I cancelled the sort, then nothing happened, but if I did not cancel the sort, then I hit an exception.

I found some information on custom sorting with the ObjectDataSource on from kubben at CodeProject. What I understood was that I needed to create a IComparer for my business object and use that within the select method that does the sorting.

My business object looks like this:

public class StatusLevel
{
private int _statusLevelID;
private string _statusLevelName;
private int _numberOfTransactions = 0;
private int _numberOfPurchaseOrders = 0;
private int _numberOfProducts = 0;

public int StatusLevelID
{
get { return _statusLevelID; }
set { _statusLevelID = value; }
}

public string StatusLevelName
{
get { return _statusLevelName; }
set { _statusLevelName = value; }
}

public int NumberOfTransactions
{
get { return _numberOfTransactions; }
set { _numberOfTransactions = value; }
}

public int NumberOfPurchaseOrders
{
get { return _numberOfPurchaseOrders; }
set { _numberOfPurchaseOrders = value; }
}

public int NumberOfProducts
{
get { return _numberOfProducts; }
set { _numberOfProducts = value; }
}
}



So, I created a comparer class that implements IComparer, like this:




public class StatusLevelComparer : IComparer<StatusLevel>
{
private string _sortColumn;
private bool _reverse;

internal StatusLevelComparer(string sortExpression)
{
_reverse
= sortExpression.ToLowerInvariant().EndsWith(" desc");
if (_reverse)
{
_sortColumn
= sortExpression.Substring(0, sortExpression.Length - 5);
}
else if (sortExpression.ToLowerInvariant().EndsWith(" asc"))
{
_sortColumn
= sortExpression.Substring(0, sortExpression.Length - 4);
}
else
{
_sortColumn
= sortExpression;
}
}

public int Compare(StatusLevel x, StatusLevel y)
{
int retVal = 0;
switch (_sortColumn)
{
case "StatusLevelID":
{
retVal
= Compare(x.StatusLevelID, y.StatusLevelID);
break;
}
case "NumberOfTransactions":
{
retVal
= Compare(x.NumberOfTransactions, y.NumberOfTransactions);
break;
}
case "NumberOfPurchaseOrders":
{
retVal
= Compare(x.NumberOfPurchaseOrders, y.NumberOfPurchaseOrders);
break;
}
case "NumberOfProducts":
{
retVal
= Compare(x.NumberOfProducts, y.NumberOfProducts);
break;
}
case "StatusLevelName":
{
retVal
= string.Compare(x.StatusLevelName, y.StatusLevelName, StringComparison.InvariantCultureIgnoreCase);
break;
}
default:
{
retVal
= Compare(x.StatusLevelID, y.StatusLevelID);
break;
}
}

return (retVal * (_reverse ? -1 : 1));
}

private static int Compare(int i1, int i2)
{
if (i1 > i2)
{
return 1;
}
if (i1 < i2)
{
return -1;
}
return 0;
}
}



According to all the documentation I read, all I would have to do now was the create a select method that took at parameter for the sortExpression and set the SortParameterName to the name of the parameter within the GridView. However, it still would not work.


After more research and testing, I realized that my Select method was a static method and I thought, well let's try. So, I changed my static select method to an instance method and suddenly everything worked. Apparently for the sort functionality to work, the select method that takes the sortExpression must be an instance method, and not a static method. Go figure.

No comments:

Post a Comment