C# 谓词如何与ListCollectionView一起工作

C# 谓词如何与ListCollectionView一起工作,c#,wpf,filter,datagrid,predicate,C#,Wpf,Filter,Datagrid,Predicate,谓词过滤器如何与ListCollectionView一起工作? 在我的例子中,我有ListCollectionView FilteredUserList。 要过滤我使用的单个值 private void AddFilterAndRefresh(string name, Predicate<User> predicate) { //Adds filter to filter list Filters.Add(name, predicate);

谓词过滤器如何与ListCollectionView一起工作? 在我的例子中,我有
ListCollectionView FilteredUserList
。 要过滤我使用的单个值

private void AddFilterAndRefresh(string name, Predicate<User> predicate)
    {
        //Adds filter to filter list
        Filters.Add(name, predicate);

        //Filters doesn't fire event automatically
        OnPropertyChanged("Filters");

        //Refresh list to by correctly displayed
        FilteredUserList.Refresh();
    }
但我想做一个类似excel的过滤器,当用户检查值时显示什么。这意味着我必须过滤多个值。当我执行
foreach(SelectedOptions中的用户u){AddFilterAndRefresh()}
Datagrid时是空的,但这是显而易见的,因为在一个过滤器之后,Datagrid显示一行。那么如何过滤多个值呢

嗯。我做了一些修改。它工作正常,但不正确。假设我有一个用户列表:

  • 表格名称部门
  • 5马吕斯一些
  • 20大流士未知
  • 20科斯特未知
  • 20格迪米纳斯未知
  • 20 Nerijus技术公司
现在,如果我按部门排除“未知”(取消选中复选框),它会过滤确定:

  • 表格名称部门
  • 5马吕斯一些
  • 20 Nerijus技术公司
现在,当我通过选项卡“20”取消选中时,它会过滤确定:

  • 表格名称部门
  • 5马吕斯一些
但当我再次查看Tabelis“20”时,它过滤错误:

  • 表格名称部门
  • 5马吕斯一些
  • 20大流士未知
  • 20科斯特未知
  • 20格迪米纳斯未知
  • 20 Nerijus技术公司
打开偏离值

我在哪里犯了错误? 视图:


视图模型:

公共类UsersViewModel:BaseViewModel { #区域私有财产 /// ///可以使用的用户信息保存列表 /// 私有ObservableCollection UserList=新ObservableCollection(); /// ///datagrid中的选定标头 /// 私有字符串SelectedColumnHeader{get;set;} /// ///选定值列表 /// 私有ObservableCollection SelectedFilters{get;set;}=new ObservableCollection(); #端区 #区域公共财产 /// ///用于类似excel的筛选功能的筛选列表 /// 公共ObservableCollection筛选器列表{get;set;} /// ///筛选器使用的每个筛选器都保存在此词典中 /// 公共列表筛选器{get;set;}=new List(); /// ///筛选用户列表 /// public ListCollectionView FilteredUserList{get;set;} /// ///当前选定对象 /// 公共用户选择的用户{get;set;} /// ///当前选定列 /// 公共DataGridColumn CurrentColumn{get;set;} 公共bool PopupVisible{get;set;} 公共UIElement筛选器按钮{get;set;} #端区 #区域命令 公共ICommand ExcludeCommand{get;set;} 公共ICommand IncludeCommand{get;set;} public ICommand removeallfilters命令{get;set;} public ICommand RemoveFilterCommand{get;set;} 公共ICommand GenerateExcelFiltServiceItemsCommand{get;set;} 公共ICommand是selectedItemsCommand{get;set;} 公共ICommand AddMultipleFiltersAndRefreshCommand{get;set;} #端区 #区域构造函数 /// ///默认构造函数 /// public UsersViewModel() { //填充用户列表 GetUsers(); //使用值设置筛选的用户列表 FilterList=新的ObservableCollection(); FilteredUserList=新建ListCollectionView(用户列表); ExcludeCommand=新的RelayParamCommand((e)=>ExcludeFilter(SelectedUser)); IncludeCommand=新的RelayParamCommand((e)=>IncludeFilter(SelectedUser)); RemoveAllFiltersCommand=newrelaycommand(()=>RemoveAllFiltersAndRefresh()); GenerateExcelFiltServiceItemsCommand=新建RelayParamCommand((e)=>GenerateExcelFilterItems(e)); IsSelectedItemsCommand=新的RelayParamCommand((e)=>IsSelectedItems(e)); //AddMultipleFiltersAndRefreshCommand=新的RelayCommand(AddMul
private bool FilterEntries(object obj)
    {
        User c = (User)obj;
        return Filters.Values.Aggregate(true, (prevValue, predicate) => prevValue && predicate(c));
    }
       <DataGrid x:Name="myGrd"   
              DataContext="{Binding ElementName=userPage, Path=DataContext}"
              SelectionMode="Single"    
              SelectionUnit="Cell"
              CurrentItem="{Binding SelectedUser, Mode=TwoWay}"
              CurrentColumn="{Binding CurrentColumn, Mode=TwoWay}"
              IsReadOnly="True"
              CanUserResizeColumns="False"
              Grid.Row="1" 
              ItemsSource="{Binding FilteredUserList}" 
              AutoGenerateColumns="True"             
              CanUserAddRows="False">
        <DataGrid.Resources>

            <!--Popup-->
            <ContextMenu x:Key="ContextMenu">
                <ContextMenu.Items>
                    <MenuItem Header="Filter by Selection" Command="{Binding IncludeCommand, Source={x:Reference vm}}"/>
                    <MenuItem Header="Filter exclude Selection" Command="{Binding ExcludeCommand, Source={x:Reference vm}}"/>
                    <MenuItem Header="Remove all Filters" Command="{Binding RemoveAllFiltersCommand, Source={x:Reference vm}}" Visibility="{Binding Filters.Count, Source={x:Reference vm}, Converter={Wpf:VisibilityConverter}}"/>
                </ContextMenu.Items>
            </ContextMenu>

            <!--Custom Datagrid header View-->               
            <Style TargetType="DataGridColumnHeader" x:Name="FilterHeader">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <StackPanel>
                                <TextBox Margin="0,0,0,10" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridColumnHeader}}, Path=Width}" />
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding}" HorizontalAlignment="Center"/>
                                    <ToggleButton Name="FilterButton" 
                                                  Content="[-F-]" 
                                                  Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}, Path=DataContext.GenerateExcelFilterViewItemsCommand}" 
                                                  CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridColumnHeader}, Path=Content}"
                                                  >
                                    </ToggleButton>

                                    <Popup Name="MyPopup"                              
                                           StaysOpen="False" 
                                           Placement="Right"
                                           IsOpen="{Binding ElementName=FilterButton, Path=IsChecked}"
                                           PlacementTarget="{Binding ElementName=FilterButton}"
                                           >
                                        <Border CornerRadius="0" BorderThickness="2" BorderBrush="{StaticResource AQBlueBrush}">
                                        <StackPanel Width="Auto" Background="{StaticResource AQBackgroundLightBrush}" MinWidth="100">
                                            <TextBlock Margin="2" Text="Filter" Foreground="{StaticResource AQVeryDarkBlueBrush}"/>
                                                <Separator/>
                                                <ListView Padding="5" 
                                                          MaxHeight="150" 
                                                          MinHeight="80" 
                                                          Background="Transparent" 
                                                          BorderThickness="0" 
                                                          ScrollViewer.VerticalScrollBarVisibility="Auto" 
                                                          ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}, Path=DataContext.FilterList}">
                                                <ListView.ItemTemplate>
                                                    <DataTemplate>
                                                        <StackPanel Orientation="Horizontal">
                                                            <CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}"
                                                                  Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}, Path=DataContext.IsSelectedItemsCommand}"
                                                                  CommandParameter="{Binding}"/>
                                                            <ContentPresenter Content="{Binding Value}" />
                                                        </StackPanel>
                                                    </DataTemplate>
                                                </ListView.ItemTemplate>
                                            </ListView>
                                            <Button Margin="2,0,2,2" 
                                                    Content="Submit" 
                                                    Foreground="{StaticResource AQVeryDarkBlueBrush}" 
                                                    Background="AliceBlue"
                                                    Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}, Path=DataContext.AddMultipleFiltersAndRefreshCommand}"/>
                                        </StackPanel>
                                        </Border>
                                    </Popup> 
                                </StackPanel>
                            </StackPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.Resources>

        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">
                <Setter Property="ContextMenu" Value="{StaticResource ContextMenu}"/>
            </Style>
        </DataGrid.CellStyle>
    </DataGrid>
private bool FilterEntries(object obj)
{
    User u = (User)obj;

    // converting original condition to ANY instead of EACH
    return Filters.Values.Aggregate(false, (prevValue, predicate) => prevValue || predicate(u));

    // looks like Filters is a Dictionary, maybe simplify condition?
    return Filters.ContainsKey(u.Name);

    // or maybe search in a List without multiple predicates
    return Filters.Keys.Any(name => name.Contains(u.Name));
}