如何在CollectionViewSource上实现多级排序

时间:2011-11-12 10:57:42

标签: wpf sorting filter collectionviewsource

我最初发布这个作为LINQ查询 - 让它工作,然后意识到我有一个问题。你不能使用LINQ查询来选择/过滤和订购CollectionViewSource中的项目(为什么我为什么不首先检查这个,为什么哦,为什么这不可能?)。

所以,我现在正试图找出如何对过滤后的CollectionViewSource进行排序。

我的CollectionViewSource绑定到ObservableCollection(Of MediaItems)。 MediaItems包含一个子/嵌套List(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. 按计数器(按升序排列)
  3. 我过滤的方式是使用这些功能:

    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似乎对排序的支持有限。我可以使用以下方法轻松对计数器进行排序:

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

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

    我想知道创建群组是否会有所帮助,但如果这将提供我正在寻找的排序功能,则无法解决。

    我已经看过转换为ListCollectionView而不是CollectionViewSource的可能性,然后使用CustomSort,但是我无法弄清楚我是如何实现它的,如果它也能提供我正在寻找的能力sort是嵌套列表中的值。

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

2 个答案:

答案 0 :(得分:2)

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

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

您可以随时将多个SortDescriptor添加到默认视图的SortCollection中,如下所示 -

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

请参阅这些链接以获取进一步的参考 -

答案 1 :(得分:0)

我不知道如何用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

祝你好运!