BindingList<T>.Sort() to behave like a List<T>.Sort()
.net, bindinglist, c#, sorting, winforms
Solution
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();
}
}
Problem
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 BindingList will sort when used in the context of a DataGridView or some other bound control including this post from StackOverflow: DataGridView sort and e.g. BindingList<T> in .NET This is all very helpful and I have implemented the code, tested, etc. and it's all working, but in my particular situation, I need to be able to support a simple call to Sort() and have that call use the default IComparable.CompareTo() to do the sorting, rather than making a call to ApplySortCore(PropertyDescriptor, ListSortDirection). The reason is because I have quite a great deal of code that's depending on the Sort() call because this particular class originally inherited from List and was recently changed to be a BindingList. So specifically, I have a class called VariableCode and a collection class called VariableCodeList. VariableCode implements IComparable and the logic in there is moderately complex based on several properties, etc... ``` 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? } } ``` I've made a few failed attempts at repurposing the ApplySortCore method in the Sort(), but what keeps thwarting me is that the ApplySortCore expects a PropertyDescriptor to do its sort and I can't figure out how to get that to use the IComparable.CompareTo() logic. Can someone point me in the right direction? Many thanks. EDIT: This is the final code based on Marc's response for future reference. ``` /// <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(); } } ```