BindingList<T>.Sort() to behave like a List<T>.Sort()

纵然是瞬间 提交于 2019-11-27 13:58:15

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();
    }    
}

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!