【问题标题】:Sorting an ObservableCollection<BusinessObject> using a custom sort order使用自定义排序顺序对 ObservableCollection<BusinessObject> 进行排序
【发布时间】:2015-04-24 17:33:27
【问题描述】:

在 WPF 中,我有一个 ObservableCollection,我需要按任意自定义顺序对其进行排序,这意味着它不仅仅是 A-Z,项目需要单独移动。

BusinessObject 有一个 ID 字段,它是一个字符串 GUID。我可以有一个字典,以排序顺序存储这些 GUID 及其分配的位置,如果是这样,我如何从单独的字典中应用排序顺序?

简而言之,我希望能够为 ObservableCollection 提供可操作的排序顺序,存储在单独的对象中。

【问题讨论】:

  • 尝试覆盖 ObservableCollection 类,让你自己拥有排序功能:D
  • 包含排序顺序的单独对象有多重要?您是否想要一个完全自定义的排序顺序,并且您不想/不能将该自定义顺序存储在您的业务对象中?

标签: c# wpf sorting


【解决方案1】:

使用ICollectionView:

var view = CollectionViewSource.GetDefaultView(businessObjects);
view.SortDescriptions.Add( SortDescription("NameOfPropertyToSortBy",ListSortDirection.Ascending ));

然后公开并绑定到视图值。虽然,实际上有绑定黑魔法,你甚至不需要更改绑定集合,但如果你这样做,它更易于维护。

【讨论】:

  • 我确实尝试过这样做,但 ICollectionView 似乎不允许我向上或向下移动单个项目。
  • 您可以通过实现 IComparer 来使用自定义排序并将其分配给 ICollectionView 上的 CustomSort 属性。
  • 这很好。我可以在我的单独排序类中使用它,并有方法将它应用到 ObservableCollection。
  • 没错。然后排序是解耦的,很好并且可测试。
【解决方案2】:

我知道您已经接受了答案,但我遇到了类似的问题,重要的是不要重新创建 ObservableCollection&lt;T&gt;,并且使用 ObservableCollection.Move() 方法移动集合中的对象(而不是删除和插入)到他们的新索引。这是为了方便 WPF 流体移动动画等。

在这种情况下,我创建了一个扩展方法,允许您以首选排序顺序传递对象的 IEnumerable&lt;T&gt;,并让 ObservableCollection&lt;T&gt; 将所有内容移动到位。

这很简单,所以我把它贴在这里以防对任何人有用:

public static class ObservableCollectionExtensions
{
    public static void MatchSort<T>(this ObservableCollection<T> collection, IEnumerable<T> collectionToMatchSortOrder)
    {
        int newIndex = 0;

        foreach (var item in collectionToMapSortOrder.Where(item => collection.Contains(item)))
        {
            collection.Move(collection.IndexOf(item), newIndex);
            newIndex++;
        }
    }
}

注意:这远非万无一失,因为它理想情况下依赖于可观察集合中存在的所有对象都存在于IEnumerable&lt;T&gt;中。

【讨论】:

  • 这将帮助我,当然还有其他人,赞成!
猜你喜欢
  • 2010-12-21
  • 1970-01-01
  • 2014-04-19
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多