【问题标题】:How to implement multiple levels of sorting on a CollectionViewSource如何在 CollectionViewSource 上实现多级排序
【发布时间】:2011-11-12 10:57:42
【问题描述】:

我最初将此作为 LINQ 查询发布 - 让它工作,然后意识到我遇到了问题。您不能使用 LINQ 查询来选择/过滤和排序 CollectionViewSource 中的项目(为什么我不先检查一下,为什么这不可能?)。

所以,我现在正在尝试研究如何对过滤后的 CollectionViewSource 进行排序。

我的 CollectionViewSource 绑定到 ObservableCollection(Of MediaItems)。 MediaItems 包含一个子/嵌套列表(Of AdvertOptions)。

父 ObservableCollection(Of MediaItems) - 类的结构如下:

MediaItems
 .ID (int)
 .Src (string)
 .Advert (bool)
 .AdOptions As List(Of AdvertOptions)
 .Counter (int)

AdvertOptions class consists of:
 .Age (int)
 .Gender (int)
 .Priority (int)

我正在过滤掉任何不符合以下条件的 MediaItem:

MediaItems.Advert = true
AdOptions.Age = x (parameter within triggered function called to perform the filter/sort)
AdOptions.Gender = y (parameter within triggered function called to perform the filter/sort)

在 CollectionViewSource 被过滤后,我需要根据两个排序顺序对项目进行排序,以便可以使用 CollectionViewSource 导航方法(MoveCurrentToX 等)在我的应用程序中导航生成的 CollectionViewSource 项目。

我需要应用的排序顺序是:

  1. AdOptions.Priority(按降序排列)
  2. 按计数器(按升序排列)

我过滤的方式是使用这些函数:

Public Shared Sub FilterByAdvertisement(ByVal Item As Object, ByVal e As FilterEventArgs)

    Dim MediaObjectItem As MediaObject = TryCast(e.Item, MediaObject)

    If Not MediaObjectItem.IsAdvertisingMedia = True Then

        e.Accepted = False

    End If

End Sub

Public Shared Sub FilterByAvertisementOption(ByVal Item As Object, ByVal e As FilterEventArgs)

    Dim MediaObjectItem As MediaObject = TryCast(e.Item, MediaObject)

    Dim Items = From m In MediaObjectItem.AdOptions Select m Where m.Age = Current.Age And m.Gender = Current.Gender
    If Items.Count = 0 Then

        e.Accepted = False

    End If

End Sub

仅供参考,我添加过滤器如下:

Public AdvertisingDataView As CollectionViewSource

AddHandler AppLocal.AdvertisingDataView.Filter, AddressOf FilterByAdvertisement
AddHandler AppLocal.AdvertisingDataView.Filter, AddressOf FilterByAdvertisementOption

我现在需要弄清楚如何对过滤后的项目进行排序。问题是,CollectionViewSource 似乎对排序的支持有限。我可以使用以下方法轻松对 Counter 进行排序:

AdvertisingDataView.SortDescriptions.Add(New SortDescription("Counter", ListSortDirection.Ascending))

但这是我的次要排序 - 我想先按 AdOptions.Priority 排序(需要子选择正确的项目),然后按 Counter。

我想知道创建组是否会有所帮助,但无法确定这是否会提供我正在寻找的排序功能。

我已经研究了转换为 ListCollectionView 而不是 CollectionViewSource 的可能性,然后使用 CustomSort,但我不知道如何实现这一点,以及它是否还能提供我正在寻找的功能sort 是嵌套列表中的一个值。

任何人都可以帮助我实现我的成果吗?

【问题讨论】:

    标签: wpf sorting filter collectionviewsource


    【解决方案1】:

    您可以在 CollectionViewSource 的默认视图上实现多级排序。 WPF 自动生成的视图基本上有 3 种类型,它们都派生自 CollectionView 基类:

    • ListCollectionView -> 在集合实现 IList 时创建。
    • BindingListCollectionView -> 在集合实现 IBindingList 时创建。
    • EnumerableCollectionView -> 当集合只实现 IEnumerable 时创建。

    您总是可以像这样将多个 SortDescriptor 添加到默认视图的 SortCollection -

    ListCollectionView lcv =
    (ListCollectionView)CollectionViewSource.GetDefaultView(myCollection);
    lcv.SortDescriptions.Add(new SortDescription(…));
    

    请参阅这些链接以获取更多参考 -

    【讨论】:

    • 您好,感谢您提供的信息。我在使用 SortDescriptor 时遇到的一个问题。如何实现这一点,以便仅使用嵌套 AdOptions 列表中的一个优先级项进行排序?
    • 链接已失效。
    【解决方案2】:

    我不知道如何用 VB 编写它,但我可以用 c# 向你展示它是如何制作的:

    YourListView = CollectionViewSource.GetDefaultView(tempListView
    .OrderBy(x => x.FirstSorting)
    .ThenBy(y => y.SecondSorting));
    

    看看如何在 VB 中做同样的事情,你会解决这个问题的。

    这里有一个链接 - http://linqsamples.com/linq-to-objects/ordering/ThenBy-lambda-csharp

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2021-03-11
      • 2011-05-09
      • 2021-08-25
      • 1970-01-01
      • 2021-08-24
      • 1970-01-01
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      相关资源
      最近更新 更多