在多个复选框上筛选 ICollectionView

本文关键字:筛选 ICollectionView 复选框 | 更新日期: 2023-09-27 18:27:25

我目前有一份包含 27,000 家公司的列表,这些公司都至少属于 3 个类别中的 1 个,SubcontractorsSuppliersPlanthire 。所有这些公司都被加载到一个ICollectionView中,这是DataGridItemsSource

我以前能够做的是根据Model的一个属性过滤ICollectionView。例如,如果我有一个作业列表,并且所有作业都附加了一个ITName属性,我可以做这样的事情;

private void OnCheckBoxCheck(object sender, RoutedEventArgs e)
{
    var checkedEmployees = new HashSet<string>();
    foreach (CheckBox checkBox in _employees.Children)
    {
        if (checkBox.IsChecked == true)
        {
            checkedEmployees.Add((string)checkBox.Content);
            checkedEmployees.Add((string)checkBox.Tag);
        }
    }
    JobsCollectionView.Filter =
        job => checkedEmployees.Contains((job as JobModel).ITName);        
}

现在的问题

现在的问题是我正在尝试过滤CompanyModel的多个属性。从中取出不相关的部分,它看起来像这样;

public class CompanyModel
{
    public int Subcontractor { get; set; }
    public int Supplier { get; set; }
    public int Planthire { get; set; }
}

我想做的是,如果检查了Subcontractor CheckBox但其他未选中,则仅显示Subcontractors。如果同时选中SubcontractorSupplier CheckBoxes,则显示适合SubcontractorSupplier类别的Companies。这是我到目前为止所尝试的,但它没有实现这一目标;

private void FilterCompanyType(object sender, RoutedEventArgs e)
{
    var checkedCompanyFilters = new HashSet<string>();
    foreach (CheckBox checkBox in companyTypes.Children)
    {
        if (checkBox.IsChecked == true)
        {
            checkedCompanyFilters.Add((string)checkBox.Tag);
        }
    }
    if (subbieCheckBox.IsChecked == true)
    {
        CompanyICollectionView.Filter =
            company => checkedCompanyFilters.Contains((company as CompanyModel).Subcontractor.ToString());
    }
    if (supplierCheckBox.IsChecked == true)
    {
        CompanyICollectionView.Filter =
                company => checkedCompanyFilters.Contains((company as CompanyModel).Supplier.ToString());
    }
    if (planthireCheckBox.IsChecked == true)
    {
        CompanyICollectionView.Filter =
            company => checkedCompanyFilters.Contains((company as CompanyModel).Planthire.ToString());
    }          
}

如何修改此方法以使其达到我想要的效果?

在多个复选框上筛选 ICollectionView

应将公司模型更改为对公司类型使用enum,对密钥使用单个int。 应使用 [Flags] 属性声明enum,以便可用于布尔运算。 然后,您的筛选器如下所示:

CompanyICollectionView.Filter =
    company => checkedCompanyFilters.Where(
        ((company as CompanyModel).CompanyType & CompanyTypes.Whatever) 
            == CompanyTypes.Whatever).Key.ToString();

您可以组合多个筛选条件:

var isSubbie = subbieCheckBox.IsChecked == true;
var isSupplier = supplierCheckBox.IsChecked == true;
...
CompanyICollectionView.Filter = company =>
{
    var model = (CompanyModel)company;
    return isSubbie && checkedCompanyFilters.Contains(model.Subcontractor.ToString()) ||
        isSupplier && checkedCompanyFilters.Contains(model.Supplier.ToString()) ||
        ...
};

我以为checkedCompanyFilters的是一组不同的分包商,但看起来你只想按一个分包商过滤。然后简单地将上面的返回线更改为这样的东西(我不确定您如何定义公司是分包商,是Subcontractor > 0时吗?

    return isSubbie && model.Subcontractor > 0 ||
        isSupplier && model.Supplier > 0 ||
        ...

我仍然想要同样Suppliers Subcontractors,即 model.Subcontractor > 0 && model.Suppliers > 0如果isSubbie && isSupplier

然后只需将return替换为:

    return (isSubbie ? model.Subcontractor > 0 : model.Subcontractor == 0) &&
        (isSupplier ? model.Supplier > 0 : model.Supplier == 0) &&
        ...

或:

    return (isSubbie && model.Subcontractor > 0 || !isSubbie && model.Subcontractor == 0) &&
        (isSupplier && model.Supplier > 0 || !isSupplier && model.Supplier == 0) &&
        ...