Friday, April 29, 2011

3 steps to enable automatic sorting of business object using BindingList

1. Create these 2 classes, just COPY AND PASTE!
You need to have "using System.ComponentModel" wherever you put these


    internal class SortComparer<T> : IComparer<T>
    {
        private PropertyDescriptor m_PropDesc = null;
        private ListSortDirection m_Direction = ListSortDirection.Ascending;

        public SortComparer(PropertyDescriptor propDesc, ListSortDirection direction)
        {
            m_PropDesc = propDesc;
            m_Direction = direction;
        }

        int IComparer<T>.Compare(T x, T y)
        {
            object xValue = m_PropDesc.GetValue(x);
            object yValue = m_PropDesc.GetValue(y);
            return CompareValues(xValue, yValue, m_Direction);
        }

        private int CompareValues(object xValue, object yValue, ListSortDirection direction)
        {
            int retValue = 0;
            if (xValue is IComparable) //can ask the x value 
            {
                retValue = ((IComparable)xValue).CompareTo(yValue);
            }
            else if (yValue is IComparable) //can ask the y value 
            {
                retValue = ((IComparable)yValue).CompareTo(xValue);
            }
            //not comparable, compare string representations 
            else if (!xValue.Equals(yValue))
            {
                retValue = xValue.ToString().CompareTo(yValue.ToString());
            }
            if (direction == ListSortDirection.Ascending)
                return retValue;
            else
                return retValue * -1;
        }
    }
    public class SortableBindingList<t> : BindingList<t>
    {
        private bool m_Sorted = false;
        private ListSortDirection m_SortDirection = ListSortDirection.Ascending;
        private PropertyDescriptor m_SortProperty = null;

        protected override bool SupportsSortingCore
        {
            get
            {
                return true;
            }
        }

        protected override bool IsSortedCore
        {
            get
            {
                return m_Sorted;
            }
        }

        protected override ListSortDirection SortDirectionCore
        {
            get
            {
                return m_SortDirection;
            }
        }

        protected override PropertyDescriptor SortPropertyCore
        {
            get
            {
                return m_SortProperty;
            }
        }

        protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
        {
            m_SortDirection = direction;
            m_SortProperty = prop;
            m_Sorted = true;
            var listRef = this.Items as List<t>;
            if (listRef == null)
                return;
            var comparer = new SortComparer<t>(prop, direction);

            listRef.Sort(comparer);

            OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
        }
    } 


2. In your business object that was formerly inheriting BindingList, it now needs to inherit SortableBindingList, like so:
public class BusinessObjList : SortableBindingList<BusinessObj>

3. In your DataGridView's Column Collection, set all the columns you want to be sortable to SortMode=Automatic


Reference
1. http://xiaonanstechblog.blogspot.com/2009/03/how-to-enable-column-sorting-on.html

No comments:

Post a Comment

There was an error in this gadget