CollectionViewSource排序算法

时间:2014-07-23 07:51:10

标签: c# sorting collectionviewsource

如何更改CollectionViewSource的排序算法?实际上,我发现CollectionViewSource的排序算法不稳定。我想在CollectionViewSource上使用稳定的算法。我怎么能这样做?

2 个答案:

答案 0 :(得分:3)

我设法使用自定义Comparer进行稳定排序,但它有点像一个大黑客...

就像Benjamin建议的那样,我从集合中获取ListCollectionView并使用我的自定义Comparer设置其CustomSort属性。唯一的区别是我在实例化时将集合传递给Comparer。

private void Sorting(IEnumerable collection)
{
    var view = CollectionViewSource.GetDefaultView(collection) as ListCollectionView;

    if (view != null)
    {
        view.CustomSort = new StableComparer(collection);
    }
}

然后,在我的自定义Comparer中,我使用Compare方法中的集合只是为了在比较返回零(它们相同或具有相同值)时回退到项目索引。

public class StableComparer : IComparer
{
    public IEnumerable Collection { get; set; }

    public StableComparer(IEnumerable collection)
    {
        Collection = collection;
    }

    public int Compare(object x, object y)
    {
        IComparable x_Comparable = x as IComparable;
        IComparable y_Comparable = y as IComparable;

        if (x_Comparable != null && y_Comparable != null)
        {
            var comparison = x_Comparable.CompareTo(y_Comparable);

            // A zero value means x and y are equivalent for sorting, and they could
            //  be rearranged by an unstable sorting algorithm
            if (comparison == 0 && Collection != null)
            {
                // IndexOf is an extension method for IEnumerable (not included)
                var x_Index = Collection.IndexOf(x);
                var y_Index = Collection.IndexOf(y);

                // By comparing their indexes in the original collection, we get to
                //  preserve their relative order
                if (x_Index != -1 && y_Index != -1)
                    comparison = x_Index.CompareTo(y_Index);
            }

            return comparison;
        }

        return 0;
    }
}

我还在测试这个,所以我无法保证这会一直有效......例如,一个问题是如何更新Comparer中的Collection属性。或支持两种排序方向。

但是我认为这个想法很清楚,虽然很糟糕,正如我所说的那样。

答案 1 :(得分:2)

您可能需要查看how to implement your custom sorting logic

简而言之,将比较器设置为:

private void Sort(object sender, RoutedEventArgs args)
{
    BlogPosts posts = (BlogPosts)(this.Resources["posts"]);
    ListCollectionView lcv = (ListCollectionView)(CollectionViewSource.GetDefaultView(posts));
    lcv.CustomSort = new SortPosts();
}

并按照以下方式实施:

public class SortPosts : IComparer
{
    public int Compare(object x, object y)
    {
        (…)
    }
}