【发布时间】:2016-04-07 21:49:59
【问题描述】:
我目前有一个DataGrid,其中包含我根据两件事过滤的公司 - 一个是用户可以根据公司名称、城镇或邮政编码过滤的搜索框。看起来像这样;
按名称/城镇/邮政编码过滤
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 时,我每次都在创建一个新的 CompanyICollectionView.Fiilter。有没有办法过滤已经过滤的ICollectionView?
编辑(添加动态过滤器):
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;
}
【问题讨论】:
-
两个过滤器是否使用相同的项目来源?
-
DataGrid具有相同的ItemsSource是的,(CompanyICollectionView) -
您的
dynamic_Filter来自哪里?从criteria创建? -
添加即编辑