Хотя я еще не до конца понимаю вашу сделку, я сделаю попытку с PredicateBuilder , который является частью сборки LINQKit, которую вы можете загрузить здесь .
Таким образом, фильтрация по нескольким столбцам станет легкой.Возможно, вы рассмотрите возможность сброса привязки вашего ObjectListView
элемента управления после того, как ваша исходная коллекция будет отфильтрована.
В общем, я хотел бы сделать следующее:
- Загрузить данные;
- Отображать их с помощью привязки данных;
- После того, как столбец будет выбран для фильтра, вызовите метод «Фильтр», который будет применять ваши предикаты;
- Восстановите контрольс новой отфильтрованной коллекцией.
Пожалуйста, обратитесь к документации PredicateBuilder по ссылке, предоставленной ранее.Другой пример построения динамических фильтров иллюстрируется здесь: « Как бы этот запрос преобразовался в динамическое выражение Linq? » для поисковой системы, которую я реализовал.
В моем случае фильтры были применены непосредственно к результатам базы данных.Кроме того, он может даже использоваться в вашей ситуации с данными в памяти, поскольку он основан на Linq.
Я уверен, что смогу предоставить дополнительную помощь, когда вы опубликуете пример кода для фильтрации информации..
РЕДАКТИРОВАТЬ # 1
После того, как я прочитал предоставленный пример кода, вот то, что, как я считаю, сработает.Что касается свойства Searchable, я не знаком с этим подходом, поэтому, возможно, я могу пропустить что-то важное в вашем коде, и если это так, не стесняйтесь указать мне, что я мог упустить.=)
Обратите внимание, что я предполагаю, что все ваши данные являются строковыми, поскольку я проверяю, является ли ваш элемент данных нулевым или пробелом.Кроме того, на мой взгляд, отфильтровать набор результатов - это отобразить только те записи, которые соответствуют определенному критерию.Вы не хотите видеть то, что не соответствует критерию.Это то же самое, что и предложение WHERE в SQL.
public class FilterCriterion {
public bool HasEmployeeName { get { return !string.IsNullOrWhiteSpace(EmployeeName); } }
public bool HasEmployeeNumber { get { return !string.IsNullOrWhiteSpace(EmployeeNumber); } }
public bool HasDepartment { get { return !string.IsNullOrWhiteSpace(Department); } }
public string EmployeeName { get; set; }
public string EmployeeNumber { get; set; }
public string Department { get; set; }
}
Класс FilterCriterion должен использоваться для применения любого фильтра, который вы хотите использовать в отношении вашего источника данных, коллекции или чего-либо еще.
var employees = LoadEmployeesFromUnderlyingDataStore();
var criterion = new FilterCriterion();
switch(searchMeth) {
case "Name": filter.EmployeeName = "the name to filter by"; break;
case "EmployeeNumber": filter.EmployeeNumber = "the number to filter by"; break;
case "Department": filter.Department = "the department to filter by"; break;
}
var filter = PredicateBuilder.True<Employee>(); // assuming you have an employee class.
if (criterion.HasEmployeeName)
filter.And(e => e.Name.ContainsLike(criterion.EmployeeName));
if (criterion.HasEmployeeNumber)
filter.And(e => e.EmployeeNumber.ContainsLike(criterion.EmployeeNumber));
if (criterion.HasDepartment)
filter.And(e => e.Department.ContainsLike(criterion.Department));
var filteredEmployees = employees.Where(filter);
// Supply your ObjectListView the way you're used to and this shall function.
Кроме того, вы могли бы также, если вам приходится иметь дело с такими строковыми переменными, написать метод расширения ContainsLike
для строкового класса.
namespace System {
public static class StringExtensions {
public static bool ContainsLike(this string input, string value) {
if (string.IsNullOrWhiteSpace(input) || string.IsNullOrWhiteSpace(value)) return false;
input = input.ToLower().RemoveDiacritics();
value = value.ToLower().RemoveDiacritics();
if (string.IsNullOrWhiteSpace(input) || string.IsNullOrWhiteSpace(value)) return false;
return input.Contains(value);
}
public static string RemoveDiacritics(this string input) {
return input == null ? null :
Encoding.ASCII.GetString(Encoding.GetEncoding(1251).GetBytes(input));
}
}
}
Надеюсь, это поможет, иначе сообщите мне о том, что я неправильно понялна ваш вопрос, и мы постараемся выяснить это вместе.
Если вам понадобится версия этого кода на VB, я постараюсь перевести, насколько мне известно, на VB.
Thisкод предоставляется как есть и не тестировался, за исключением обоих методов расширения строки.