Reputation: 2965
I currently have a list of 27,000 Companies that all fit into at least 1 of 3 categories, Subcontractors
, Suppliers
and Planthire
. All of these companies are loaded into an ICollectionView
, which is the ItemsSource
for a DataGrid
.
what I've previously been able to do in the past is filter the ICollectionView
based on one property of a Model
. For example if I had a list of jobs, and all jobs had an ITName
property attached, I could do something like this;
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);
}
The Problem Now
The problem now is that I am trying to filter on multiple properties of a CompanyModel
. With irrelevant parts taken out of it it looks like this;
public class CompanyModel
{
public int Subcontractor { get; set; }
public int Supplier { get; set; }
public int Planthire { get; set; }
}
What I would like to do is if the Subcontractor
CheckBox
is checked but the others aren't, only show Subcontractors
. If the Subcontractor
and Supplier
CheckBoxes
are both checked, show Companies
that fit into the Subcontractor
AND Supplier
categories. This is what I have attempted so far, however it does not achieve this;
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());
}
}
How can I modify this method so that it achieves what I would like it to?
Upvotes: 2
Views: 343
Reputation: 21979
You can combine multiple filter conditions:
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()) ||
...
};
I thought what checkedCompanyFilters
is a set of different subcontractors but it looks like you want to filter by just one. Then simply change above return line to something like this (I am not sure how do you define company is subcontractor, is it when Subcontractor > 0
?):
return isSubbie && model.Subcontractor > 0 ||
isSupplier && model.Supplier > 0 ||
...
I would still like
Subcontractors
that are alsoSuppliers
, i.e.model.Subcontractor > 0 && model.Suppliers > 0
ifisSubbie && isSupplier
Then simply replace return
with either:
return (isSubbie ? model.Subcontractor > 0 : model.Subcontractor == 0) &&
(isSupplier ? model.Supplier > 0 : model.Supplier == 0) &&
...
or:
return (isSubbie && model.Subcontractor > 0 || !isSubbie && model.Subcontractor == 0) &&
(isSupplier && model.Supplier > 0 || !isSupplier && model.Supplier == 0) &&
...
Upvotes: 1
Reputation: 1041
Your company model should be changed to use an enum
for the type of company and a single int
for the key. The enum
should be declared with the [Flags]
attribute so that it can be used for Boolean operations. Then your filters look like this:
CompanyICollectionView.Filter =
company => checkedCompanyFilters.Where(
((company as CompanyModel).CompanyType & CompanyTypes.Whatever)
== CompanyTypes.Whatever).Key.ToString();
Upvotes: 1