I have re-written my DataGrid
filtering method to try to improve performance and I feel that although this is the fastest yet, there is still room for improvement on some of the slower machines my program runs on.
The DataGrid
is bound to an ObservableCollection
, as the user enters text into my searchBox
each CompanyModel
that matches the filter is added into a filter ListBox
. The ListBox
is limited to the first 25 CompanyModels
so as to enhance performance. Here is the method that is called as the user types;
private void FilterCompanies()
{
FilteredCompanies = new ObservableCollection<CompanyModel>();
FilteredCompanies.Clear();
string searchText = CleanseText(searchBox.Text.ToLower());
foreach (CompanyModel company in AllCompanies)
{
if (!string.IsNullOrEmpty(searchText))
{
if (FilteredCompanies.Count <= 25)
{
if (CompanyMatchesFilters(company))
{
if (CleanseText(company.Name.ToLower()).Contains(searchText) ||
CleanseText(company.Town.ToLower()).Contains(searchText) ||
CleanseText(company.Postcode.ToLower()).Contains(searchText))
{
FilteredCompanies.Add(company);
}
}
}
}
}
if (FilteredCompanies.Count > 0)
{
companiesListBox.ItemsSource = FilteredCompanies;
companiesListBox.Visibility = Visibility.Visible;
}
else
{
companiesListBox.ItemsSource = null;
companiesListBox.Visibility = Visibility.Collapsed;
}
}
From the code you can see there are two more methods involved in the filtering;
CompanyMatchesFilters
private bool CompanyMatchesFilters(CompanyModel company)
{
foreach (FilterItem item in firstListBoxItems)
{
if (item.ID == 1 && company.CurrentStatus != 1)
{
return false;
}
if (item.ID == 2 && company.Subcontractor != 1)
{
return false;
}
if (item.ID == 3 && company.Supplier != 1)
{
return false;
}
if (item.ID == 4 && company.Planthire != 1)
{
return false;
}
if (item.ID == 5 && company.Architect != 1)
{
return false;
}
if (item.ID == 6 && company.QS != 1)
{
return false;
}
if (item.ID == 7 && company.ProjectManager != 1)
{
return false;
}
if (item.ID == 8 && company.StructEng != 1)
{
return false;
}
if (item.ID == 9 && company.ServiceEng != 1)
{
return false;
}
}
return true;
}
CleanseText
private static Regex badChars = new Regex("[^A-Za-z0-9']");
private string CleanseText(string text)
{
return badChars.Replace(text, "");
}
I would be very grateful if I could have some advice on;
- A: How to improve my code in general
- B(maybe more importantly): How to further improve the performance of my methods if at all possible
firstListBoxItems
? \$\endgroup\$ – RBarryYoung Nov 18 '16 at 22:14Contains(..)
also check their lengths and exit the loop when the strings are shorter than the newsearchText
. \$\endgroup\$ – RBarryYoung Nov 19 '16 at 14:26AllCompanies
? \$\endgroup\$ – RBarryYoung Nov 20 '16 at 13:34firstListBoxItems
is anObservableCollection
. I like your second suggestion I'll look into that. There's "alot" inAllCompanies
, around 28000. \$\endgroup\$ – CBR Nov 21 '16 at 9:00