Cool ObservableCollection Sort Extension

2 posts, 0 answers
  1. Garry
    Garry avatar
    205 posts
    Member since:
    Nov 2010

    Posted 24 Jun 2010 Link to this post

    I came across the need to be able to sort my ObservableCollections the other day and I found a nice code snippet demonstrating how to sort an ObservableCollection even if the collection type does not support IComparable. I added the ReverseCompare/Descending sort just in case. Anyhow thought it was a neat piece of code and hope it may help some others out there.

    Enjoy!

    public static class CollectionSorter  
        {  
            public static void Sort<T>(this ObservableCollection<T> collection, Comparison<T> comparison)  
            {  
                var comparer = new Comparer<T>(comparison);  
     
                List<T> sorted = collection.OrderBy(x => x, comparer).ToList();  
     
                for (int i = 0; i < sorted.Count(); i++)  
                    collection.Move(collection.IndexOf(sorted[i]), i);  
            }  
     
            public static void DescendingSort<T>(this ObservableCollection<T> collection, Comparison<T> comparison)  
            {  
                var comparer = new ReverseComparer<T>(comparison);  
     
                List<T> sorted = collection.OrderBy(x => x, comparer).ToList();  
     
                for (int i = 0; i < sorted.Count(); i++)  
                    collection.Move(collection.IndexOf(sorted[i]), i);  
            }       
        }  
     
        internal class Comparer<T> : IComparer<T>  
        {  
            private readonly Comparison<T> comparison;  
     
            public Comparer(Comparison<T> comparison)  
            {  
                this.comparison = comparison;  
            }
            #region IComparer<T> Members  
     
            public int Compare(T x, T y)  
            {  
                return comparison.Invoke(x, y);  
            }
            #endregion  
        }  
     
        internal class ReverseComparer<T> : IComparer<T>  
        {  
            private readonly Comparison<T> comparison;  
     
            public ReverseComparer(Comparison<T> comparison)  
            {  
                this.comparison = comparison;  
            }
            #region IComparer<T> Members  
     
            public int Compare(T x, T y)  
            {  
                return -comparison.Invoke(x, y);  
            }
            #endregion  
        } 

    then you can use it on your ObservableCollections as such. 
    private void Log(LogEntry log)  
            {  
                LoggedEvents.Add(log);  
                LoggedEvents.DescendingSort((x, y) => x.TimeStampString.CompareTo(y.TimeStampString));  
            }        
     
            private ObservableCollection<LogEntry> entries = new ObservableCollection<LogEntry>();  
            public ObservableCollection<LogEntry> LoggedEvents  
            {  
                get 
                {                  
                    return entries;  
                }  
                set 
                {  
                    entries = value;  
                    RaisePropertyChanged(LoggedProperty);  
                }  
            } 
  2. Jonas
    Jonas avatar
    1 posts
    Member since:
    Jul 2012

    Posted 27 Nov 2012 Link to this post

    The orderby-operation is fast, but since you do an indexof for each item in the list, the extension-method will have Ordo(n2) which is a bad thing... the collection should be ordered in place with a quicksort to keep performance good when working with large lists.
  3. UI for WPF is Visual Studio 2017 Ready
Back to Top