2015-12-02 107 views
0

我有一个DataGrid,其中包含Jobs的数目。这些Jobs中的每一个都有一个与之关联的员工,我想根据哪些员工在这些工作上进行筛选。所以我有四个CheckBoxes;基于复选框过滤ObservableCollection

<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.ItemsSource = _jobDataService.GetJobList();将此集合绑定到我的DataGrid。正如我之前所说的,每项工作的部分模型都与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; } 
} 

我的问题真的是我如何可以筛选此集合,则势必要基于的CheckBoxes的选择DataGrid

+1

如果您需要过滤,最好使用ListCollectionView。 var lcv = new ListCollectionView(yourObservableCollection); yourDataGrid。的ItemsSource = LCV; – bamanow

回答

2

当您绑定到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类,因此代码ISN”这里显示T):

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方法来获得此)。

每个复选框控制具有点击事件处理程序(它们都指向相同的方法),只需通过复选框迭代来构建其当前“检查”员工名字的列表(checkedEmployees),然后设置集合视图的Filter属性以应用适当的过滤逻辑。基本上过滤器是一个从视图中获取项目的代理(在您的情况下为JobModel对象),并返回一个布尔值,指示该特定对象是否应包含在视图中。在这里,我只是检查来自作业的员工姓名是否包含在一组过滤的员工姓名中。

有一点需要注意的是ICollectionView排序和过滤的性能可能是非常大的列表的问题,在这种情况下,您可能需要通过从原始数据集构造一个全新的列表来排序/过滤。我会先尝试收集视图的方法,然后看看你如何继续。

+0

感谢您的回答,这仍然适用于过滤'DataGrid'而不是'ListBox'? – CBreeze

+0

我没有真正使用过'DataGrid',但我相信它就像'ListBox'一样从'ItemsControl'派生,所以是的。 –

+0

我让它工作正常,非常感谢。 – CBreeze