CollectionViewSource Live Sorting is not working

3.4k Views Asked by At

I have created a user control containing a ListBox which is bound through a CollectionViewSource. The ListBox has CheckBoxes for the user to do multiple selection on. I would like the list to be sorted with the selected CheckBoxes at the top. I am hoping for this to work as soon as the user selects or unselects something. I can't seem to find anything thing that does this through xaml. What am I doing wrong?

In my xaml

<CollectionViewSource x:Key="SortedItems"
                      Source="{Binding Items, ElementName=Selector}"
                      IsLiveSortingRequested="True">
        <CollectionViewSource.LiveSortingProperties>
            <System:String>IsSelected</System:String>
        </CollectionViewSource.LiveSortingProperties>
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="IsSelected"
                                 Direction="Descending" />
            <scm:SortDescription PropertyName="CodeDescriptionText" />
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>

and my list box

<ListBox x:Name="ItemsControl"
         SelectionMode="Multiple"
         ItemsSource="{Binding Source={StaticResource SortedItems}}"
         ItemTemplate="{Binding ItemTemplate, ElementName=Selector}"
         ItemContainerStyle="{StaticResource ListBoxItemStyle}"
         Grid.Row="1"
         Grid.ColumnSpan="3">
2

There are 2 best solutions below

1
On

In your ItemTemplate, are you binding bool properties to the Checkbox.IsChecked properties? If you are, then you should be able to set that property as the SortDescription.PropertyName property as it seems that you are doing. If not, then that is what you need to do.

2
On

I also had the same issue, and eventually I found out the problem is with the data source, and I suspect that your issue is the same as mine.

While CollectionViewSource can work with a number of different types of data sources, not all of them will work with live sorting. To ensure everything work smoothly, it is best to use an ObservableCollection of items that implement INotifyPropertyChanged for the data source.

But if you have to use a custom collection class instead of ObservableCollection, then make sure that class implements IList, not just the generic IList<>. If you don't, live sorting will most likely be disabled. And to ensure all other areas work smoothly, I strongly advise you to also implement INotifyCollectionChanged and INotifyPropertyChanged for it as well.

No matter which collection class you use, the items contained in it still have to implement INotifyPropertyChanged. There are no other ways around it.