Фильтрация большой коллекции (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); }