If you need to filter, sort or group some ObservableCollection the CollectionViewSource is the answer to your needs.

With this class you will be able to keep your ObservableCollection items in their original state and make some views to show data the way you want.

Here you can see an example:

Install Microsoft Silverlight

Both lists are bound to the same observableCollection. The first one gets filtered whenever the comboBox changes its selection and the second one is alphabetically sorted, as you can see.

Using the CollectionViewSource class is very easy. You just have to instantiate it and add it some filter or sorting:

Dim cs As New CollectionViewSource
cs.SortDescriptions.Add(New SortDescription("Name", ListSortDirection.Ascending))
cs.Source = data

To add the filter you have at least two different options. You can assign a handler to the filter event or you can assign a System.Predicate:

Dim cf As New CollectionViewSource
AddHandler cf.Filter, AddressOf myFilter
cf.Source = data

where myFilter is:

Protected Sub myFilter(ByVal o As Object, ByVal e As FilterEventArgs)
        If CType(e.Item, data).Name.Contains("Joan") Then
            e.Accepted = True
        Else
            e.Accepted = False
        End If
End Sub

or

Dim cf As New CollectionViewSource
cf.Source = data
cf.View.Filter = New System.Predicate(Of Object)(AddressOf myFilter2)

where myFilter2 is:

Protected Function myFilter2(ByVal i As Object) As Boolean
        If CType(i, data).Name.Contains("Joan") Then
                  Return True
        Else
                Return False
        End If
End Function

As you can see there’s a slight difference between this two ways of handling the filter but it’s really easy. Once you have declared your CollectionViewSources you have to associated the itemsSource property of the listbox,grid or whatever to the CollectionViewSource View property:

list1.ItemsSource = cf.View

HINT: If you want to refresh the CollectionViewSource you can use the Refresh method.

cf.View.Refresh()

One of the drawbacks of the CollectionViewSource is that whenever the original collection data is modified the filter does not refresh automatically (as you can see in the example if you filter the active items and in the second list you inactive one of them – you will see it still remains, you will have to refilter again).

For now it’s enought we will see if we can solve this issue in a further post.

Download demo