您可以对源集合 ( MyCollection
) 进行排序,而不是在 XAML 中对其进行排序。
诚然,没有内置的方法来对 进行排序ObservableCollection<T>
,但实现起来并不难。这是一个 QuickSort 实现,您可以将其用作任何实现的类的扩展方法IList<T>
:
static class QuickSortExtensions
{
private static void CheckArgumentNull<T>(this T arg, string paramName) where T : class
{
if (arg == null)
throw new ArgumentNullException(paramName);
}
public static void CheckArgumentOutOfRange<T>(
this T value,
string paramName,
T min,
T max)
where T : IComparable<T>
{
if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0)
throw new ArgumentOutOfRangeException(paramName);
}
public static void QuickSort<T>(this IList<T> list)
{
Comparison<T> comparison = Comparer<T>.Default.Compare;
list.QuickSort(comparison);
}
public static void QuickSort<T>(
this IList<T> list,
IComparer<T> comparer)
{
comparer = comparer ?? Comparer<T>.Default;
list.QuickSort(comparer.Compare);
}
public static void QuickSort<T>(
this IList<T> list,
Comparison<T> comparison)
{
list.CheckArgumentNull("list");
comparison.CheckArgumentNull("comparison");
QuickSort(list, 0, list.Count - 1, comparison);
}
private static void QuickSort<T>(IList<T> list, int left, int right, Comparison<T> comparison)
{
if (right > left)
{
int pivot = left;
QuickSortPartition(list, left, right, ref pivot, comparison);
QuickSort(list, left, pivot - 1, comparison);
QuickSort(list, pivot + 1, right, comparison);
}
}
private static void QuickSortPartition<T>(IList<T> list, int left, int right, ref int pivot, Comparison<T> comparison)
{
T pivotValue = list[pivot];
list.Swap(pivot, right);
int tmpIndex = left;
for (int i = left; i < right; i++)
{
if (comparison(list[i], pivotValue) <= 0)
{
list.Swap(i, tmpIndex);
tmpIndex++;
}
}
list.Swap(tmpIndex, right);
pivot = tmpIndex;
}
private static void Swap<T>(
this IList<T> list,
int index1,
int index2)
{
list.CheckArgumentNull("list");
index1.CheckArgumentOutOfRange("index1", 0, list.Count - 1);
index1.CheckArgumentOutOfRange("index2", 0, list.Count - 1);
T tmp = list[index1];
list[index1] = list[index2];
list[index2] = tmp;
}
}
为了防止在排序过程中随着集合项目的移动而刷新视图,您可以使用DeferRefresh
:
var view = CollectionViewSource.GetDefaultView(MyCollection);
using (view.DeferRefresh())
{
MyCollection.QuickSort();
}