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