我的DataGrid
包含多个Jobs
。这些Jobs
中的每一个都有一个与之关联的员工,我想根据这些工作中的员工进行过滤。所以我有四个CheckBoxes
;
<CheckBox x:Name="employeeARad" Content="EmployeeA" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="18" Margin="7,0,0,5"/>
<CheckBox x:Name="employeeBRad" Content="EmployeeD" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="18" Margin="7,5,0,5"/>
<CheckBox x:Name="employeeCRad" Content="EmployeeC" HorizontalAlignment="Left" Margin="7,5,0,5" VerticalAlignment="Top" FontSize="18"/>
<CheckBox x:Name="employeeDRad" Content="EmployeeD" HorizontalAlignment="Left" Margin="7,5,0,5" VerticalAlignment="Top" FontSize="18"/>
我从数据库中检索并填充ObservableCollection
个数据。然后,我使用:DataGrid
将此集合绑定到我的dataGrid.ItemsSource = _jobDataService.GetJobList();
。正如我之前所说,每个工作都有一部分模型与Employee
相关联。以下是Job
;
class JobModel
{
public int CaseNumber { get; set; }
public string EmployeeName { get; set; }
public string CaseNotes { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateDeadline { get; set; }
public string CaseClient { get; set; }
}
我的问题是如何根据DataGrid
的选择过滤绑定到CheckBoxes
的此集合?
答案 0 :(得分:3)
当您绑定到WPF中的集合时,会在幕后创建从ICollectionView
派生的对象。此接口支持通过使用各种属性对集合进行排序和过滤。
我通常做的是将ObservableCollection<T>
分配给私有字段,该字段包含所有数据。然后我有一个类型ICollectionView
的相应公共属性,我应用任何排序或过滤条件。
以下是包含作业列表的简单窗口的XAML,以及按员工名称筛选列表的复选框。为了简单起见,我在工作列表中只显示了 员工姓名:
<Window x:Class="StackOverflow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel Margin="10">
<StackPanel x:Name="_employees" DockPanel.Dock="Top">
<CheckBox Content="Fred" IsChecked="True" Click="OnCheckBoxClick" />
<CheckBox Content="Wilma" IsChecked="True" Click="OnCheckBoxClick" />
<CheckBox Content="Barney" IsChecked="True" Click="OnCheckBoxClick" />
<CheckBox Content="Betty" IsChecked="True" Click="OnCheckBoxClick" />
</StackPanel>
<ListBox ItemsSource="{Binding JobsCollectionView}"
DisplayMemberPath="EmployeeName" Margin="0,10,0,0" />
</DockPanel>
</Window>
此处为此窗口的代码隐藏(我已重复使用您现有的JobModel
课程,因此此处未显示代码):
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace StackOverflow
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
_jobs = new ObservableCollection<JobModel>
{
new JobModel { EmployeeName = "Fred" },
new JobModel { EmployeeName = "Wilma" },
new JobModel { EmployeeName = "Fred" },
new JobModel { EmployeeName = "Barney" },
new JobModel { EmployeeName = "Betty" },
};
JobsCollectionView = CollectionViewSource.GetDefaultView(_jobs);
DataContext = this;
}
readonly ObservableCollection<JobModel> _jobs;
public ICollectionView JobsCollectionView { get; private set; }
void OnCheckBoxClick(object sender, RoutedEventArgs e)
{
var checkedEmployees = new HashSet<string>();
foreach (CheckBox checkBox in _employees.Children)
{
if (checkBox.IsChecked == true)
{
checkedEmployees.Add((string) checkBox.Content);
}
}
JobsCollectionView.Filter =
job => checkedEmployees.Contains((job as JobModel).EmployeeName);
}
}
}
您可以看到包含作业集合的私有_jobs
字段,以及提供对JobsCollectionView
实施的访问权限的公共ICollectionView
属性(CollectionViewSource.GetDefaultView
方法是用来获得这个)。
每个 CheckBox 控件都有一个 Click 事件处理程序(它们都指向相同的方法),它只是遍历复选框以构建一个员工名称列表目前&#34;已检查&#34; (checkedEmployees
),然后设置集合视图的Filter
属性以应用适当的过滤逻辑。基本上,过滤器是一个委托,它从视图中获取一个项目(在您的情况下为JobModel
对象)并返回一个布尔值,该值指示该特定对象是否应包含在视图中。在这里,我只是检查作业中员工的姓名是否包含在过滤员工姓名集中。
需要注意的一点是ICollectionView
排序和过滤的性能可能是非常大的列表的问题,在这种情况下,您可能需要通过从原始集合构建一个全新的列表来排序/过滤数据的。我会首先尝试集合视图方法,然后看看你是如何进行的。