DRD94 Ответов: 1

Фильтрация большой коллекции (28000 членов) по типу пользователя


То, что я попытался сделать, - это отфильтровать наблюдаемую коллекцию компаний, когда пользователь вводит текст в текстовое поле. Пользователь может установить флажки, чтобы добавить дополнительные критерии к тому,что он хотел бы найти.

Извините, если это особенно длинный пример, но, как я уже сказал, в данный момент метод очень медленный, и я ищу способы его улучшить.

Что я уже пробовал:

Главная проблема с тем,что я пробовал до сих пор, заключается в том, что это очень, очень медленно, когда пользователь вводит данные в поле поиска. Вот как я применяю фильтр в первую очередь;

CollectionViewSource.GetDefaultView(Companies).Filter = FilterCompanies;


Когда пользователь вводит текст в текстовое поле этот метод вызывается;

private void SearchBoxCallApplyFilters(object sender, TextChangedEventArgs e)
{
    CollectionViewSource.GetDefaultView(Companies).Refresh();
}


А затем метод FilterCompanies;

private bool FilterCompanies(object obj)
{
    var company = obj as CompanyModel;
    if (searchBox.Text == string.Empty)
    {
        return true;
    }
    else if (CharactersOnly(company.Name.ToLower()).Contains((CharactersOnly(searchBox.Text).ToLower()))
        || CharactersOnly(company.Town.ToLower()).Contains((CharactersOnly(searchBox.Text).ToLower()))
        || CharactersOnly(company.Postcode.ToLower()).Contains((CharactersOnly(searchBox.Text).ToLower())))
    {
        if (FilterByCheckBoxes(company))
        {
            return true;
        }

    }
    return false;
}


И, наконец, FilterByCheckBoxes способ;

private bool FilterByCheckBoxes(CompanyModel company)
{
    if (currentCheckBox.IsChecked == true && company.CurrentStatus == 1)
    {
        return true;
    }
    if (subbieCheckBox.IsChecked == true && company.Subcontractor == 1)
    {
        return true;
    }
    if (supplierCheckBox.IsChecked == true && company.Supplier == 1)
    {
        return true;
    }
    if (planthireCheckBox.IsChecked == true && company.Planthire == 1)
    {
        return true;
    }
    if (architectCheckBox.IsChecked == true && company.Architect == 1)
    {
        return true;
    }
    if (qsCheckBox.IsChecked == true && company.QS == 1)
    {
        return true;
    }
    if (projectManagerCheckBox.IsChecked == true && company.ProjectManager == 1)
    {
        return true;
    }
    if (structEngCheckBox.IsChecked == true && company.StructEng == 1)
    {
        return true;
    }
    if (servEngCheckBox.IsChecked == true && company.ServiceEng == 1)
    {
        return true;
    }
    return false;
}


CharactersOnly просто удаляет все, что не является символом из текста текстового поля;

private string CharactersOnly(string input)
{
    char[] arr = input.ToCharArray();
    arr = Array.FindAll(arr, (c => (char.IsLetterOrDigit(c))));
    return new string(arr);
}