Как да внедрите множество нива на сортиране на CollectionViewSource

Първоначално публикувах това като 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)

Филтрирам всички медийни елементи, които не отговарят на следните критерии:

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 елементи да могат да се навигират в моето приложение с помощта на методите за навигация на CollectionViewSource (MoveCurrentToX и т.н.).

Редът на сортиране, който трябва да приложа, е:

  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 изглежда има ограничена поддръжка за сортиране. Мога лесно да сортирам брояча с помощта на:

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

Но това е второстепенното ми сортиране - искам първо да сортирам по AdOptions.Priority (изисква подизбор на правилния елемент), след това по Counter.

Чудех се дали създаването на групи ще помогне, но не мога да разбера дали това ще осигури възможността за сортиране, която търся.

Разгледах възможността за преобразуване в ListCollectionView вместо CollectionViewSource, след което да използвам CustomSort, но не мога да разбера как бих могъл да внедря това и дали би предложил и възможността, която търся, като се има предвид, че основното ми сортиране е стойност в рамките на вложен списък.

Може ли някой да допринесе, за да ми помогне да постигна резултата си?

Бен


person Ben    schedule 12.11.2011    source източник


Отговори (2)


Можете да постигнете множество нива на сортиране в изгледа по подразбиране на вашия CollectionViewSource. По същество има 3 типа изгледи, автоматично генерирани от WPF, всички произлизащи от базовия клас CollectionView:

  • ListCollectionView -> Създава се, когато колекцията имплементира IList.
  • BindingListCollectionView -> Създава се, когато колекцията внедрява IBindingList.
  • EnumerableCollectionView -> Създава се, когато колекцията не прилага нищо друго освен IEnumerable.

Винаги можете да добавите към множество SortDescriptor към SortCollection на вашия изглед по подразбиране по този начин -

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

Вижте тези връзки за допълнителна справка -

person Rohit Vats    schedule 12.11.2011
comment
Хей благодаря за информацията. Имам един въпрос относно използването на SortDescriptor. Как мога да внедря това, така че да сортира, като използва само един от приоритетните елементи във вложения списък с опции за реклами? - person Ben; 13.11.2011
comment
Връзките са мъртви. - person DonBoitnott; 19.04.2021

Не знам как да го напиша на 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

Късмет!

person BAndrei    schedule 02.04.2018