CollectionViewSource how to filter data?

I bind ComboBox to objects, but I want the data to be filtered.

So far I have tried two ways:

  • "simple" one: apply the filter directly to the ObjectSet via tt LINQ to Entities
  • setting up a filtering event handler as described in msdn

I am satisfied with the first approach, primarily because the query generated in the database contains the WHERE clause, so not all data should be extracted from the remote db ....

However, approach # 2 is much more flexible if at runtime I want to change the filtering applied ... I followed the msdn example, but I get an exception, why?

So my questions are:
1. Which approach is better - 2. Why am I getting an exception?

Here is my code:

private void UserControl_Loaded(object sender, RoutedEventArgs e) { //Do not load your data at design time. if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) { //Load your data here and assign the result to the CollectionViewSource. System.Windows.Data.CollectionViewSource myCollectionViewSource = (System.Windows.Data.CollectionViewSource) this.Resources["tSCHEDEViewSource"]; // If I use this I get the data filtered on startup, but is it the right mode? //myCollectionViewSource.Source = _context.TSCHEDE.Where(s => s.KLINEA == kLinea && s.FCANC == "T").OrderBy(s => s.DSCHEDA).OrderByDescending(s => s.DSTORICO); // Instead If I apply my custom filtering logic myCollectionViewSource.Filter += new FilterEventHandler(filterSource); myCollectionViewSource.Source = _context.TSCHEDE; // ... Here i get an exception: // 'System.Windows.Data.BindingListCollectionView' view does not support filtering. ??? } } private void filterSource(object sender, FilterEventArgs e) { TSCHEDE scheda = e.Item as TSCHEDE; if (scheda != null) { if (scheda.KLINEA == 990) { e.Accepted = true; } else { e.Accepted = false; } } } 

EDIT : I tried to implement the Filter property in the view, and not set the EventHandler:

 myCollectionView = (BindingListCollectionView)myCollectionViewSource.View; myCollectionView.Filter = new Predicate<object>(Contains); public bool Contains(object de) { TSCHEDE scheda = de as TSCHEDE; return (scheda.KLINEA == 990); } 

And now I get a not very useful exception:

System.NotSupportedException: The specified method is not supported. in System.Windows.Data.CollectionView.set_Filter (value Predicate`1)

EDIT

XAML Code:

 <UserControl.Resources> <CollectionViewSource x:Key="tSCHEDEViewSource" d:DesignSource="{d:DesignInstance my:TSCHEDE, CreateList=True}" > </CollectionViewSource> <DataTemplate x:Key="SchedaTemplate"> <StackPanel Orientation="Horizontal" > <TextBlock Text="{Binding Path=KSCHEDA}" Width="60"></TextBlock> <TextBlock Text="{Binding Path=DArticolo}" Width="200"></TextBlock> <TextBlock Text=" - " Width="40"></TextBlock> <TextBlock Text="{Binding Path=DSTORICO}" Width="150"></TextBlock> </StackPanel> </DataTemplate> </UserControl.Resources> <Grid Background="PapayaWhip" DataContext="{StaticResource tSCHEDEViewSource}" DataContextChanged="StartHere" Name="rootGrid"> <ComboBox ItemTemplate="{StaticResource SchedaTemplate}" Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="23,129,0,0" Name="tSCHEDEComboBox1" SelectedValuePath="KSCHEDA" VerticalAlignment="Top" Width="393"> <ComboBox.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel /> </ItemsPanelTemplate> </ComboBox.ItemsPanel> </ComboBox> </Grid> 

Now I think the problem is with the XAML binding, not the code ...

+4
source share
2 answers

Recently, I found a solution also published in in this question in expliticy declare a collection type:

CollectionViewType = "ListCollectionView"

So, a collection type has been added to XAML:

 <CollectionViewSource x:Key="tSCHEDEViewSource" d:DesignSource="{d:DesignInstance my:TSCHEDE, CreateList=True}" CollectionViewType="ListCollectionView"> </CollectionViewSource> 

And in the code now the event handler works:

 myCollectionViewSource.Filter += new FilterEventHandler(filterSource); 

The only regret is that I did not understand why, for something obviously so simple, I have to force it "manually" in XAML ??? To me, this seems like a hack, and also very error prone ...

+5
source

check this

1) Filter CollectionView

Filtering requires a delegate (Predicate), on the basis of which the filter will occur. The predicate takes the element a based on the value true or false, which it returns; it selects or deselects the element.

 this.Source.Filter = item => { ViewItem vitem = item as ViewItem; return vItem != null && vitem.Name.Contains("A"); }; 

2) Dynamic data change

+6
source

All Articles