Nested filtering using CollectionViewSource in UserControl
I have a UserControl that displays some collection which should be filtered but the collection passed to the control might be filtered in the main window. It looks like this:
Window1.xaml
<Window x:Class="CollectionViewSourceTesting.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CollectionViewSourceTesting="clr-namespace:CollectionViewSourceTesting"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<CollectionViewSource Source="{Binding Data}" x:Key="ItemsViewSource" Filter="CollectionViewSource_Filter" />
</Window.Resources>
<Grid>
<CollectionViewSourceTesting:UserControl1 DataContext="{Binding Source={StaticResource ItemsViewSource}}" />
</Grid>
</Window>
UserControl1.xaml
<UserControl x:Class="CollectionViewSourceTesting.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<Grid.Resources>
<CollectionViewSource Source="{Binding}" x:Key="cvs" Filter="CollectionViewSource_Filter" />
</Grid.Resources>
<ListBox ItemsSource="{Binding Source={StaticResource cvs}}" />
</Grid>
</UserControl>
This is not working since CollectionViewSource.Source doesn't accept ListCollectionView, it throws an exception "'System.Windows.Data.ListCollectionView' is not a valid value for property 'Source'.".
I figured I could use DataContextChanged event in UserControl to manually add filtering to the ListCollectionView but that would not be nesting and I would also need to set ListBox.ItemsSource prop开发者_开发百科erty manually. I would use the existing view and change the Filter property. What I want to do is to create another view using CollectionViewSource so I could put in xaml. Is that possible?
I want my UserControl to handle normal collection as well as CollectionViews.
This might not be the same but it is something that is working for me. I did it this way because I did not know filter was available for CollectionViewSource. I use a trigger and viability. You could use a converter for some more advanced filter logic. The user can can change the value for the trigger and the screen screen dynamically updates. MyGabeLib.Search.SelectedDoc.DocFields is an ObservableCollection.
<CollectionViewSource x:Key="curDocFields"
Source="{Binding Path=MyGabeLib.Search.SelectedDoc.DocFields}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="FieldDefApplied.AppliedDisplayOrder" Direction="Ascending"/>
<scm:SortDescription PropertyName="FieldDefApplied.FieldDef.DispName"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
<Style TargetType="ListViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=FieldDefApplied.AppliedDispDetail, Mode=OneWay}" Value="False" PresentationTraceSources.TraceLevel="High">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
I found that if I change a value and want the sort to be refreshed I need:
CollectionViewSource.GetDefaultView(lbFields.ItemsSource).Refresh();
精彩评论