Click here to Skip to main content
15,880,543 members
Articles / Web Development / ASP.NET
Article

Generic sorting of customer objects for ObjectDataSource (ASP.NET)

Rate me:
Please Sign up or sign in to vote.
3.77/5 (7 votes)
23 Oct 2008GPL3 28K   30   2
Generic sorting of customer objects for ObjectDataSource in ASP.NET.

Introduction

The class PropertyComparer provides the possibility for data-access-components to enable sorting for customer objects when using an ObjectDataSource.

Background

ASP.NET 2.0 includes the controls GridView and ObjectDataSource. You can define which methods of your data-access-component is used by the ObjectDataSource. If the Select method returns a DataSet or a DataTable, you can use paging and sorting for the GridView out of the box.

If you want to work with collections of business-objects instead of DataSet/DataTable, you have to implement the sorting yourself. I wrote a generic comparer for use with all my business-objects.

Using the code

Use a GridView where you define the DataSourceId, and enable sorting:

ASP.NET
<asp:GridView     ID="exampleGridView" runat="server" 
        DataSourceID="exampleDataSource" 
        AllowSorting="True" ... >

Define the ObjectDataSource:

ASP.NET
<asp:ObjectDataSource     ID="exampleDataSource" runat="server" 
            TypeName="ExampleDataAccessComponent" 
            SelectMethod="Select" 
            SortParameterName="orderBy" ... >

Write your data-access-component implementing the Select method:

C#
[DataObject()]
public sealed class ActivityDac
{
    private string myConnectionString;
    private DbProviderFactory myFactory;


    public ActivityDac()
    {
        ConnectionStringSettings cs = 
           ConfigurationManager.ConnectionStrings[" ... "];
        myFactory = DbProviderFactories.GetFactory(cs.ProviderName);
        myConnectionString = cs.ConnectionString;
    }


    [DataObjectMethod(DataObjectMethodType.Select, true)]
    public Activity[] Select(string orderBy)
    {
        List<BusinessClass> list = new List<BusinessClass>();
        using (DbConnection con = myFactory.CreateConnection())
        {
            con.ConnectionString = myConnectionString;
            using (DbCommand cmd = myFactory.CreateCommand())
            {
                cmd.Connection = con;
                cmd.CommandText = " ... ";

                DbParameter p = myFactory.CreateParameter();
                ...
                cmd.Parameters.Add(p);

                con.Open();
                DbDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleResult);

                while (reader.Read())
                {
                    BusinessClass o = new BusinessClass(reader.GetInt32(0));
                    ..
                    list.Add(o);
                }
            }
        }

        if (!String.IsNullOrEmpty(orderBy))
        {
            PropertyComparer<BusinessClass> comparer = 
              new PropertyComparer<BusinessClass>(orderBy);
            list.Sort(comparer);
        }

        return list.ToArray();
    }
}

Here is the code for the PropertyComparer:

C#
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Collections;

namespace Example
{
    public class PropertyComparer<T> : IComparer<T>
    {
        private enum SortType
        {
            Descending = -1,
            Ascending = 1
        }


        private SortType mySortDirecton;
        private string mySortPropertyName;


        public PropertyComparer(string sortString)
        {
            if (sortString == null)
                throw new ArgumentNullException("sortString");
            if (sortString.Length == 0)
                throw new ArgumentOutOfRangeException("sortString");

            if (sortString.ToLower().EndsWith(" desc"))
            {
                mySortPropertyName = sortString.Substring(0, sortString.Length - 5);
                mySortDirecton = SortType.Descending;
            }
            else
            {
                if (sortString.ToLower().EndsWith(" asc"))
                    mySortPropertyName = sortString.Substring(0, sortString.Length - 4);
                else
                    this.mySortPropertyName = sortString;

                this.mySortDirecton = SortType.Ascending;
            }
        }


        #region IComparer<T> Members

        public int Compare(T x, T y)
        {
            if ((x == null) && (y == null))
                return 0;
            if (x == null)
                return -(int)mySortDirecton;
            if (y == null)
                return (int)mySortDirecton;

            PropertyInfo p = x.GetType().GetProperty(mySortPropertyName);
            if (p == null)
                throw new ApplicationException();

            object vX = p.GetValue(x, null);
            object vY = p.GetValue(y, null);

            if ((vX == null) && (vY == null))
                return 0;
            if (vX == null)
                return -(int)mySortDirecton;
            if (vY == null)
                return (int)mySortDirecton;

            return (int)mySortDirecton * Comparer.DefaultInvariant.Compare(vX, vY);
        }

        #endregion
    }
}

History

  • Oct. 24, 2008: 9:23 - Corrected typo.

    License

    This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


    Written By
    Software Developer
    Austria Austria
    This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

    Comments and Discussions

     
    GeneralSorting should be made on all objects - Pin
    toebens28-Oct-08 23:04
    toebens28-Oct-08 23:04 
    hi,
    the scenario you describe is only sorting the result that was returned to the grid.
    if you use paging for example the sorting should be done on all data. in your example you would need to get all the objects from the datasource to fill your list else only the result that was shown on the grid is sorted.
    for such a case there are client script solutions for sorting a table with javascript, too. i just saw an article in the code project newsletter about using jquery to sort a gridview.
    greetings, tobi
    GeneralRe: Sorting should be made on all objects - Pin
    Andreas Kranister29-Oct-08 0:08
    Andreas Kranister29-Oct-08 0:08 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.