4

我有一个非常小的整数集合,我在 custom 中显示ItemsControl。我不担心性能,因为集合太小了。我希望这些项目按升序显示,但不知道这样做的最佳方式。我已经成功地使用 aCollectionViewSource和 aSortDescription对更复杂的对象进行排序,但它似乎需要一个属性名称来排序。我意识到我可以保持底层集合排序或将我的整数包装在引用类型中以使用SortDescription,但两者似乎都过分了。我错过了什么吗?

我想做这样的事情MyCollection,类型在哪里ObservableCollection<int>

<Grid.Resources>
    <CollectionViewSource x:Key={sortedView} Source={Binding MyCollection}>
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription Direction="Ascending" PropertyName="???" />
        </CollectionViewSource.SortDescriptions>
    <CollectionViewSource>
<Grid.Resources>

...

<ItemsControl ItemsSource={StaticResource sortedView} />
4

2 回答 2

3

只需.用作属性名称:

<scm:SortDescription Direction="Ascending" PropertyName="." />
于 2012-11-19T21:39:37.767 回答
0

您可以对源集合 ( 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();
}
于 2012-11-19T21:33:48.877 回答