【问题标题】:Sorting ObservableCollection<T>排序 ObservableCollection<T>
【发布时间】:2013-10-14 15:26:51
【问题描述】:

我有两个单独的可观察集合,其中 T 是用户定义的类。这些集合绑定到列表视图和树视图。我想按排序顺序显示集合的项目。我似乎没有在列表和树视图上找到任何排序功能。集合中的元素可以在运行时删除/添加。实现这一目标的最佳方法是什么?

提前致谢。干杯!

【问题讨论】:

标签: wpf listview sorting treeview observablecollection


【解决方案1】:

您可以通过扩展ObservableCollection&lt;T&gt; 类,使用内部Move 方法轻松实现此行为。这是一个简化的例子:

public class SortableObservableCollection<T> : ObservableCollection<T>
{
    public SortableObservableCollection(IEnumerable<T> collection) : 
        base(collection) { }

    public SortableObservableCollection() : base() { }

    public void Sort<TKey>(Func<T, TKey> keySelector)
    {
        Sort(Items.OrderBy(keySelector));
    }

    public void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
    {
        Sort(Items.OrderBy(keySelector, comparer));
    }

    public void SortDescending<TKey>(Func<T, TKey> keySelector)
    {
        Sort(Items.OrderByDescending(keySelector));
    }

    public void SortDescending<TKey>(Func<T, TKey> keySelector, 
        IComparer<TKey> comparer)
    {
        Sort(Items.OrderByDescending(keySelector, comparer));
    }

    public void Sort(IEnumerable<T> sortedItems)
    {
        List<T> sortedItemsList = sortedItems.ToList();
        for (int i = 0; i < sortedItemsList.Count; i++)
        {
            Items[i] = sortedItemsList[i];
        }
    }
}

感谢@ThomasLevesque 提供了更高效的Sort 方法

然后你可以像这样使用它:

YourCollection.Sort(c => c.PropertyToSortBy);

【讨论】:

  • 另外,请不要说这个解决方案不起作用,只是因为你在将它应用到你的代码时遇到了一些困难。您误导了可能正在搜索相同功能的其他用户。
  • 这个解决方案效率非常...它的复杂度至少为 O(n²)。大多数排序算法的复杂度为 O(n log n)。
  • 那是因为直接访问Items不会触发CollectionChanged事件。它可以很容易地修复:只需将Items[i] 替换为this[i]。另一种选择是在排序结束时使用 Action = Reset 触发 CollectionChanged 事件。这样,您只需触发一个事件,UI 只需刷新一次。
  • @Aleksey,真的吗???你有多不成熟?我在Binding to a method in DataContext 帖子上对你投了反对票,因为你提供了一个绝对不正确的答案。所以你的反应是找到我的任何一个答案,这样你就可以对我投反对票作为报复?你真是太可怜了……完全难以置信 StackOverflow 用户会以这种方式行事……非常令人失望。
  • @Aleksey,声望点对我来说并不重要,而且自从投票后你似乎改变了态度,我接受你之前的道歉。请在未来投票之前三思而后行……在某些特定条件下应该使用它们。我确实接受,当我对你的答案投反对票时,我本可以留下更好的评论,所以我希望我们都能从中学到一些东西。
【解决方案2】:
  private void ApplySort(IEnumerable<T> sortedItems)
  {
     var sortedItemsList = sortedItems.ToList();
     for (int i = 0; i < sortedItemsList.Count; i++)
     {
        if((object)(this[i]) != (object)(sortedItemsList[i]))
           this[i] = sortedItemsList[i];
     }
  }

可以减少 CollectionChanged 事件的数量以获得更好的性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多