C# 谓词如何与ListCollectionView一起工作
谓词过滤器如何与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 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技术公司
- 表格名称部门
- 5马吕斯一些
- 表格名称部门
- 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));
}