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:
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
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.
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.