过滤基于CheckBoxes的ObservableCollection

时间:2015-12-02 12:09:10

标签: c# wpf checkbox datagrid

我的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的此集合?

1 个答案:

答案 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排序和过滤的性能可能是非常大的列表的问题,在这种情况下,您可能需要通过从原始集合构建一个全新的列表来排序/过滤数据的。我会首先尝试集合视图方法,然后看看你是如何进行的。