Another DataGrid (ObservableCollection) Filtering Method 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&lt;CompanyModel&gt;();
    FilteredCompanies.Clear();

    string searchText = CleanseText(searchBox.Text.ToLower());

    foreach (CompanyModel company in AllCompanies)
    {
        if (!string.IsNullOrEmpty(searchText))
        {
            if (FilteredCompanies.Count &lt;= 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 &gt; 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 &amp;&amp; company.CurrentStatus != 1)
        {
            return false;
        }
        if (item.ID == 2 &amp;&amp; company.Subcontractor != 1)
        {
            return false;
        }
        if (item.ID == 3 &amp;&amp; company.Supplier != 1)
        {
            return false;
        }
        if (item.ID == 4 &amp;&amp; company.Planthire != 1)
        {
            return false;
        }
        if (item.ID == 5 &amp;&amp; company.Architect != 1)
        {
            return false;
        }
        if (item.ID == 6 &amp;&amp; company.QS != 1)
        {
            return false;
        }
        if (item.ID == 7 &amp;&amp; company.ProjectManager != 1)
        {
            return false;
        }
        if (item.ID == 8 &amp;&amp; company.StructEng != 1)
        {
            return false;
        }
        if (item.ID == 9 &amp;&amp; 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
You can refactor this into LINQ query for (arguably) better readability.

AllCompanies.Where(c =&gt; CompanyMatchesFilters(c))
            .Where(c =&gt; CleanseText(company.Name).Contains(searchText)
                     || CleanseText(company.Town).Contains(searchText) 
                     || CleanseText(company.Postcode).Contains(searchText))
            .Take(25);


As for performance - nothing in the code you've shown strikes me as potential performance bottleneck. You will probably have to run a profiler to pinpoint it. One thing in particular you might want to look at is what triggers the search and how often it is executed. For example, if I enter 10 chars in search box, do I search 1 or 10 times? While the filtering logic looks fairly lightweight, the performance implications of recreating 25 item templates in UI on every keystroke can be severe (depending on how complex the DataTemplate is). Rx has some nice extensions that might help in throttling UI events.

P.S. Whats the point of removing all meaningful characters in CleanseText? What characters are you interested in then? This is extremely unclear, you should document that portion of your code.