How to set a filter for a DataGrid ItemSource via

2019-04-06 00:04发布

问题:

I have a DataGrid bound to a CollectionViewSource in XAML.

<Window.Resources>
  <local:MainWindowViewModel x:Key="ViewModel"/>
  <CollectionViewSource x:Key="cvsEntries" 
                        Source="{Binding LogEntriesStore, 
                                 Source={StaticResource ViewModel}}"/>
</Window.Resources>

LogEntriesStore is an ObservableCollection (LogEntry is a DTO that's not important in this discussion)

The DataGrid is declared as:

<DataGrid AutoGenerateColumns="False" 
          Margin="0" 
          Name="dataGrid1" 
          ItemsSource="{Binding Source={StaticResource cvsEntries}}" 
          IsReadOnly="True">

Now I have context menus on various cells in this DataGrid, to kick off a request for filtering. Right click on a cell, and pick filter to filter all the rows, and show only this particular value.

The MVVM gets the request to filter, but the now the tricky bit. How do I set the filter on the CollectionViewSource?

(as an aside -- this would have been a walk in the park with a Silverlight PagedCollectionView but that doesn't seem to be available in WPF, is that right?)

回答1:

Very simple. You just need to move the collection view inside the view model:

  1. In MainWindowViewModel define a property of type ICollectionView:

    public ICollectionView LogEntriesStoreView { get; private set; }
    
  2. Right after you have initialized the LogEntriesStore property, you need to initialize the LogEntriesStoreView property with the following code:

    LogEntriesStoreView = CollectionViewSource.GetDefaultView(LogEntriesStore);
    
  3. Then you need to remove the CollectionViewSource from XAML and modify the ItemsSource binding to point to the newly created collection view property:

    <DataGrid AutoGenerateColumns="False" 
              Margin="0" 
              Name="dataGrid1" 
              ItemsSource="{Binding LogEntriesStoreView, Source={StaticResource ViewModel}}" 
              IsReadOnly="True">
    

That's it. Now you have the access to the collection view inside your view model, where you can modify the filter.



回答2:

There are several solutions to your problem, but in my opinion, the best solutions are the ones which uses only styles with the standard WPF DataGrid control without inventing a new inherited DataGird type or depending on another third-party control. The followings are the best solutions I found:

  • Option 1: which I personally use: Automatic WPF Toolkit DataGrid Filtering
  • Option 2: Auto-filter for Microsoft WPF DataGrid