В настоящее время у меня есть DataGrid
, заполненный компаниями, которые я фильтрую на основе двух вещей: один - это поле поиска, которое пользователь может фильтровать на основе имени, города или почтового индекса Компании. Это выглядит так:Фильтр и фильтр ICollectionView WPF
Фильтр по названию/Город/Почтовый индекс
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());
}
}
Второй метод фильтрации основан на типе компании. Это делается путем выбора числа CheckBoxes
. Этот метод выглядит следующим образом;
Фильтр по типу компании
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);
}
Оба этих методов фильтрации выглядеть отлично на свои собственные. Проблема возникает, когда я хочу фильтровать фильтр, который уже был применен к DataGrid. Например, пользователь хочет отфильтровать тип компании, поэтому они выбирают currentCheckBox
, supplierCheckBox
и subbieCheckBox
. Это возвращает всех текущих поставщиков, которые также являются субподрядчиками.
Это все еще возвращает список из 5000 компаний, поэтому пользователь затем хочет использовать функцию поиска, чтобы найти компанию, которой они знают имя. Но он не ищет фильтр CompanyICollection
, он сбрасывает его и фильтрует весь список (27000 компаний).
Я считаю, что проблема в том, что я создаю новый CompanyICollectionView.Fiilter
каждый раз, когда я хочу найти существующий. Есть ли способ фильтровать уже отфильтрованный ICollectionView
?
EDIT (Добавлено 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;
}
ли вы использовать одни и те же товары Источник для обоих фильтров? – ZwoRmi
«DataGrid» имеет тот же «ItemsSource», да, ('CompanyICollectionView') – CBreeze
Откуда берутся ваши' dynamic_Filter'? Создано из 'критериев'? – ZwoRmi