4

custom に表示している int の非常に小さなコレクションがありますItemsControl。コレクションが少ないので、パフォーマンスは心配ありません。アイテムを昇順で表示したいのですが、最適な方法がわかりません。CollectionViewSourceより複雑なオブジェクトを並べ替えるために a を使用して成功しましたSortDescriptionが、並べ替えるにはプロパティ名が必要なようです。基になるコレクションをソートしたままにするか、 int を参照型にラップして を使用できることはわかっています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

MyCollectionXAML で並べ替えるのではなく、ソース コレクション ( ) を並べ替えることができます。

確かに、を並べ替える組み込みの方法はありません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 に答える