代码之家  ›  专栏  ›  技术社区  ›  Paul Prewett

绑定列表<T>。Sort()的行为类似于List<T>。排序()

  •  22
  • Paul Prewett  · 技术社区  · 17 年前


    DataGridView sort and e.g. BindingList<T> in .NET

    public class VariableCode : ...  IComparable ...
    {
        public int CompareTo(object p_Target)
        {
            int output = 0;
            //some interesting stuff here
            return output;
        }
    }
    
    public class VariableCodeList : SortableBindingList<VariableCode>
    {
        public void Sort()
        {
            //This is where I need help
            //  How do I sort this list using the IComparable
            //  logic from the class above?
        }
    }
    


      /// <summary>
      /// Sorts using the default IComparer of T
      /// </summary>
      public void Sort()
      {
         sort(null, null);
      }
      public void Sort(IComparer<T> p_Comparer)
      {
         sort(p_Comparer, null);
      }
      public void Sort(Comparison<T> p_Comparison)
      {
         sort(null, p_Comparison);
      }
      private void sort(IComparer<T> p_Comparer, Comparison<T> p_Comparison)
      {
    
         m_SortProperty = null;
         m_SortDirection = ListSortDirection.Ascending;
    
         //Extract items and sort separately
         List<T> sortList = new List<T>();
         this.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 = RaiseListChangedEvents;
         RaiseListChangedEvents = false;
         try
         {
            ClearItems();
            sortList.ForEach(item => this.Add(item));
         }
         finally
         {
            RaiseListChangedEvents = oldRaise;
            ResetBindings();
         }
    
      }
    
    2 回复  |  直到 9 年前
        1
  •  17
  •   Marc Gravell    17 年前

    仅仅为了进行排序而模拟属性可能有点过头了。 Comparer<T>.Default

    • 将数据提取到 List<T> 或类似
    • 对提取的数据进行排序
    • 禁用通知
    • 发送“重置”消息

    顺便说一句,您也应该在现有排序过程中禁用通知。

    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();
        }    
    }
    
        2
  •  10
  •   SolarX    14 年前

    我也遇到了同样的问题,这篇文章帮助我解决了这个问题!

    当我将这个解决方案(基于Marc和Paul的代码)实现为扩展并添加了两个简单的排序方法时,我想与您分享:

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

    希望这有帮助。