I currently have a DataGrid filled with companies that I am filtering based on two things - one is a search box that the user can filter based on the Company's Name, Town or Postcode. This looks like this;
Filter by Name/Town/Postcode
private void FilterDataGrid()
{
try
{
var searchText = CharactersOnly(searchBox.Text);
CompanyICollectionView.Filter = (obj =>
{
CompanyModel compDetails = obj as CompanyModel;
if (compDetails == null)
{
return true;
}
if (compNameRad.IsChecked == true)
{
return CompanyContains(compDetails.Name, searchText.ToLower());
}
if (compTownRad.IsChecked == true)
{
return CompanyContains(compDetails.Town, searchText.ToLower());
}
if (compPcodeRad.IsChecked == true)
{
return CompanyContains(compDetails.Postcode, searchText.ToLower());
}
return false;
});
if (dataGrid.Items.Count == 0) // There are no companies with this filter on, clear the label
{
compDetailsLabel.Content = string.Empty;
}
else
{
dataGrid.SelectedIndex = 0;
}
}
catch (Exception ex)
{
var hEs = new HandleExceptionService();
hEs.HandleException(ex.ToString());
}
}
The second method for filtering is based on the Company's type. This is done by the selection of a number of CheckBoxes. This method looks like this;
Filter by Company Type
private void FilterCompanyType(object sender, RoutedEventArgs e)
{
criteria.Clear();
if (currentCheckBox.IsChecked == true && nonCurrentCheckBox.IsChecked == false)
{
criteria.Add(new Predicate<CompanyModel>(x => x.CurrentStatus == 1));
}
else if (nonCurrentCheckBox.IsChecked == true && currentCheckBox.IsChecked == false)
{
criteria.Add(new Predicate<CompanyModel>(x => x.CurrentStatus == 0));
}
else if (nonCurrentCheckBox.IsChecked == true && currentCheckBox.IsChecked == true)
{
criteria.Add(new Predicate<CompanyModel>(x => (x.CurrentStatus == 1 || x.CurrentStatus == 0)));
}
if (subbieCheckBox.IsChecked == true)
{
criteria.Add(new Predicate<CompanyModel>(x => x.Subcontractor == 1));
}
if (supplierCheckBox.IsChecked == true)
{
criteria.Add(new Predicate<CompanyModel>(x => x.Supplier == 1));
}
if (planthireCheckBox.IsChecked == true)
{
criteria.Add(new Predicate<CompanyModel>(x => x.Planthire == 1));
}
if (architectCheckBox.IsChecked == true)
{
criteria.Add(new Predicate<CompanyModel>(x => x.Architect == 1));
}
if (qsCheckBox.IsChecked == true)
{
criteria.Add(new Predicate<CompanyModel>(x => x.QS == 1));
}
if (projectManagerCheckBox.IsChecked == true)
{
criteria.Add(new Predicate<CompanyModel>(x => x.ProjectManager == 1));
}
if (structEngCheckBox.IsChecked == true)
{
criteria.Add(new Predicate<CompanyModel>(x => x.StructEng == 1));
}
if (servEngCheckBox.IsChecked == true)
{
criteria.Add(new Predicate<CompanyModel>(x => x.ServiceEng == 1));
}
foreach (CheckBox checkBox in companyFilters.Children)
{
if (!CheckCheckBoxes())
{
dataGrid.ItemsSource = null;
compDetailsLabel.Content = string.Empty;
}
else
{
dataGrid.ItemsSource = CompanyICollectionView;
CompanyICollectionView.Filter = dynamic_Filter;
SetSelectedCompany(selectedIndex);
dataGrid.SelectedIndex = 0;
}
}
var nfi = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone();
nfi.NumberGroupSeparator = ",";
numberOfCompaniesLabel.Content = "Number of Companies: " + dataGrid.Items.Count.ToString("#,#", nfi);
}
Both of these filtering methods look fine on their own. The issue comes when I want to filter a filter that has already been applied to the DataGrid. For example, the user wants to filter down the company type, so they select the currentCheckBox, the supplierCheckBox and the subbieCheckBox. This returns all current suppliers that are also subcontractors.
This still returns a list of 5000 companies, so the user then wants to use the search functionality to find the company they know the name of. But it doesn't search the filtered CompanyICollection, it resets it and filters the entire list (27000 companies).
I believe that the problem is that I'm creating a new CompanyICollectionView.Fiilter every time, when I want to search an existing one. Is there a way to filter an already filtered ICollectionView?
EDIT (Added dynamic_Filter):
private bool dynamic_Filter(object item)
{
CompanyModel company = item as CompanyModel;
bool isIn = true;
if (criteria.Count() == 0)
return isIn;
isIn = criteria.TrueForAll(x => x(company));
return isIn;
}