BindingList.Sort() to behave like a List.Sort()

前端 未结 2 754
南笙
南笙 2020-12-01 13:59

I am attempting to write a SortableBindingList that I can use for my application. I have found lots of discussion about how to implement basic sorting support so that the B

相关标签:
2条回答
  • 2020-12-01 14:48

    I had the same problem and this post helped me solve it!

    As I implemented this solution (based on Marc's and Paul's code) as an extension and added two simple sort methods, I would like to share it with you:

    public static void SortAscending<T, P>(this BindingList<T> bindingList, Func<T, P> sortProperty)
        {
            bindingList.Sort(null, (a, b) => ((IComparable<P>)sortProperty(a)).CompareTo(sortProperty(b)));
        }
        public static void SortDescending<T, P>(this BindingList<T> bindingList, Func<T, P> sortProperty)
        {
            bindingList.Sort(null, (a, b) => ((IComparable<P>)sortProperty(b)).CompareTo(sortProperty(a)));
        }
        public static void Sort<T>(this BindingList<T> bindingList)
        {
            bindingList.Sort(null, null);
        }
        public static void Sort<T>(this BindingList<T> bindingList, IComparer<T> comparer)
        {
            bindingList.Sort(comparer, null);
        }
        public static void Sort<T>(this BindingList<T> bindingList, Comparison<T> comparison)
        {
            bindingList.Sort(null, comparison);
        }
        private static void Sort<T>(this BindingList<T> bindingList, IComparer<T> p_Comparer, Comparison<T> p_Comparison)
        {
    
           //Extract items and sort separately
            List<T> sortList = new List<T>();
            bindingList.ForEach(item => sortList.Add(item));//Extension method for this call
            if (p_Comparison == null)
            {
                sortList.Sort(p_Comparer);
            }//if
            else
            {
                sortList.Sort(p_Comparison);
            }//else
    
            //Disable notifications, rebuild, and re-enable notifications
            bool oldRaise = bindingList.RaiseListChangedEvents;
            bindingList.RaiseListChangedEvents = false;
            try
            {
            bindingList.Clear();
            sortList.ForEach(item => bindingList.Add(item));
            }
            finally
            {
            bindingList.RaiseListChangedEvents = oldRaise;
            bindingList.ResetBindings();
            }
    
        }
    
        public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
        {
            if (source == null) throw new ArgumentNullException("source");
            if (action == null) throw new ArgumentNullException("action");
    
            foreach (T item in source)
            {
                action(item);
            }
        }
    

    Hope this is helpful.

    0 讨论(0)
  • 2020-12-01 15:02

    Emulating a property just to do the sort is probably overkill. The first thing to look at is Comparer<T>.Default. It might, however, turn out that the easiest thing to do is to:

    • extract the data into List<T> or similar
    • sort the extracted data
    • disable notifications
    • reload the data
    • re-enable notifications
    • send a "reset" message

    btw, you should be disabling notifications during your existing sort, too.

    public void Sort() {
        // TODO: clear your "sort" variables (prop/order)
    
        T[] arr = new T[Count];
        CopyTo(arr, 0);
        Array.Sort(arr);
        bool oldRaise = RaiseListChangedEvents;
        RaiseListChangedEvents = false; // <=== oops, added!
        try {
            ClearItems();
            foreach (T item in arr) {
                Add(item);
            }
        } finally {
            RaiseListChangedEvents = oldRaise;
            ResetBindings();
        }    
    }
    
    0 讨论(0)
提交回复
热议问题