h1

"Automatic sorting is only supported with DataView, DataTable, and DataSet" or else How to sort list in ObjectDataSource

October 7, 2008

 

When I wanted to sort GridView which used ObectDataSource I obtained exception Automatic sorting is only supported with DataView.  (WTF!! why?!)

 

So, becouse I changed my job I wanted to solve this problem ASAP.

First at all you should do is

  • make your universal Comparer.
  • Update data object for ObjectDataSource
  • Update code behind for your page
  • Update ASPX file – sortable columns + add ObjectDatasource parameters

UniversalComparer

 

/// <summary>
///
Provides universal comparing for particular UDT’s.
///
</summary>
///
<typeparam name=”T”></typeparam>
/// <example>listBO.Sort(new UniversalComparer<BO>(sortExpression, SortDirection.Ascending));
</example>
public class UniversalComparer<T> : IComparer<T>
{
private readonly string _sortExpression;
private readonly short _sortDirection;
public UniversalComparer(string expression, SortDirection sortDirection)
{
_sortExpression = expression;
_sortDirection = (short)sortDirection;
}

/// <summary>
///
Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
///
</summary>
/// <param name=”x”>The first object to compare.
</param>
/// <param name=”y”>The second object to compare.
</param>
///
<returns>
/// Value Condition Less than zero<paramref name=”x”/> is less than <paramref name=”y”/>.Zero<paramref name=”x”/> equals <paramref name=”y”/>.Greater than zero<paramref name=”x”/> is greater than <paramref name=”y”/>
.
///
</returns>
public int Compare(T x, T y)
{
if (string.IsNullOrEmpty(_sortExpression)) return 0;
Type t = x.GetType();
PropertyInfo pInfo = t.GetProperty(_sortExpression);
if (pInfo != null)
  return (_sortDirection) * Comparer.DefaultInvariant.Compare(pInfo.GetValue(x, null), pInfo.GetValue(y, null));
throw new NullReferenceException(string.Format(“Property doesn’t exists in the instance”));
}

 /// <summary>
///
Determinates direction of sorting.
///
</summary>
public enum
SortDirection
{
Ascending = 1,
Descending = -1
}
}

 

Update code behind for your page

Add delegated method which is calling when Sorting event is fired.

protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
ObjectDataSource1.SelectParameters["sortExpression"].DefaultValue = e.SortExpression;
ObjectDataSource1.SelectParameters["sortDirection"].DefaultValue = RevertSortDirection(ObjectDataSource1.SelectParameters["sortDirection"].DefaultValue);
e.Cancel = true;
}

/// <summary>
/// Reverts the sort direction, which is parsed from string. Return value and input parameters are in string format.
/// Values must be equal to Values of SortDirection enum.
/// </summary>
/// <param name=”sortDirectionString”>The sort direction string.</param>
/// <returns></returns>
private string RevertSortDirection(string sortDirectionString)
{
SortDirection sortDirection ;
if (string.IsNullOrEmpty(sortDirectionString))
sortDirection = SortDirection.Descending;
else
sortDirection = (SortDirection) Enum.Parse(typeof(SortDirection), sortDirectionString, false);
SortDirection direction = sortDirection == SortDirection.Ascending ? SortDirection.Descending : SortDirection.Ascending;
return Enum.GetName(typeof(SortDirection), direction);
}

 

e.Cancel = true – this is very important line which tell us, that firing event must be cancelled in this moment. In other words: It block  Automatic sorting is only supported with DataView error

 

Update DataSource of ObjectDataSource

In this part I will update SELECT for ObjectDataSource

public List<BO> GetBOs(string sortExpression, string sortDirection)
{
listBO.Add(new BO(10, “Kolar”));
listBO.Add(new BO(11, “Kopecky”));
listBO.Add(new BO(10, “Pavel”));
listBO.Add(new BO(12, “Banan”));
listBO.Add(new BO(14, “Opice”));

 if (!string.IsNullOrEmpty(sortExpression))
{
if (string.IsNullOrEmpty(sortDirection) || sortDirection.ToUpper() == “DESCENDING”)
listBO.Sort(new UniversalComparer<BO>(sortExpression, UniversalComparer<BO>.SortDirection.Ascending));
else
listBO.Sort(new UniversalComparer<BO>(sortExpression, UniversalComparer<BO>.SortDirection.Descending));
}
return listBO;
}

 

For Select method I am telling which column and how to sort.

 

Update ASPX ObjectdataSource + Grid

<form id=”form1″ runat=”server”>
<div
>
<asp:GridView ID=”GridView1″ runat=”server” AllowSorting=”True”
AutoGenerateColumns=”False” DataSourceID=”ObjectDataSource1″ Height=”241px” onsorting=”GridView1_Sorting” Width
=”396px”>
<Columns
>
<asp:BoundField DataField=”Name” HeaderText=”Name” SortExpression=”Name”
/>
<asp:BoundField DataField=”Id” HeaderText=”Id” SortExpression=”Id”
/>
</Columns
>
</asp:GridView
>
</div>

<asp:ObjectDataSource ID=”ObjectDataSource1″ runat=”server” SelectMethod=”GetBOs” TypeName=”BOListDataSource”>
<SelectParameters
>
<asp:Parameter Name=”sortExpression” Type=”string” Direction=”input”
/>
<asp:Parameter Name=”sortDirection” Type=”string” Direction=”input”
/>
</SelectParameters
>
</asp:ObjectDataSource
>
</form>

 

Links

Leave a Comment