Если вы хотите, чтобы фильтровать данные на стороне клиента, ICollectionView
(ListCollectionView
в частности) является то, что вы хотите:
public class ViewModel
{
// this is a property for filtering
public bool Sex
{
get { ... }
set
{
if (_sex != value)
{
_sex = value;
OnPropertyChanged();
PersonListView.Refresh();
}
}
}
// this is a property for filtering too
public string Country
{
// call PersonListView.Refresh in setter, as in Sex property setter
}
// this is a property for binding to DataGrid
public ICollectionView PersonListView
{
get
{
if (_personListView == null)
{
_personList = LoadPersons();
_personListView = new ListCollectionView(_personList)
{
Filter = p => ShouldViewPerson((Person)p);
}
}
return _personListView;
}
}
private bool ShouldViewPerson(Person p)
{
// implement filtering logic here;
// e.g.:
return p.Country.StartsWith(Country) && p.Sex == Sex;
}
private ListCollectionView _personListView;
private List<Person> _personList;
}
просмотров Коллекция являются своего рода прогнозов, которые используются для упорядочения , фильтрации и группировки исходных коллекций/последовательностей. Вы можете думать о них как о сочетании методов LINQ's Where
, GroupBy
, OrderBy
и Select
, которые будут применены к исходной коллекции и результирующей последовательности, которые будут связаны для просмотра.
По умолчанию, если вы выставили некоторую коллекцию из модели просмотра, механизм привязки данных создает для вас коллекционное представление по умолчанию. Но если вы хотите получить настраиваемое поведение, например фильтрацию, вы можете самостоятельно создать коллекцию и выставить ее вместо коллекции.
Я не хочу, чтобы загрузить данные каждый раз, когда фильтр изменения пользователя условия, потому что volumne данных очень огромны, скорость загрузки очень медленно
Если вы можете, рассмотреть фильтрации на стороне сервера. Фильтрация на стороне клиента выполняется в памяти и может потреблять много системных ресурсов.
UPDATE
Если вы хотите множественного выбора страны из списка фильтрации, вы можете заменить скалярное Country
Countries
свойство сбора и переписать логику фильтрации. Что-то вроде этого:
// this is a filter item
public class CountryFilterItem : INotifyPropertyChanged
{
public string CountryName { ... }
public bool IsChecked { ... }
}
public class ViewModel
{
// this property is a replacement for "Country";
// bind it to some ItemsControl is the filter view
public IEnumerable<CountryFilterItem> Countries
{
get { return _countries; }
}
// fill filter somewhere;
// when filling, subscribe on `PropertyChanged` event of each item;
// when user will change IsChecked for item, you'll update filter:
//
// var country = new Country { CountryName = "Zimbabwe" };
// country.PropertyChanged += (sender, args) =>
// {
// if (propertyName == "IsChecked")
// {
// PersonListView.Refresh();
// }
// };
// _countries.Add(country);
private List<CountryFilterItem> _countries;
// filtering logic
private bool ShouldViewPerson(Person p)
{
// implement filtering logic here;
// e.g.:
return _countries.Any(_ => _.IsChecked && _.CountryName == p.Country) && p.Sex == Sex;
}
// other code here...
}
Привет @Dennis, спасибо вам ответ. В вашем коде Sex и Country являются двумя свойствами в ViewModel, если мой фильтр поддерживает множественный выбор, где я должен вызвать метод Refresh? Например, я хочу показать мужчин в США и Великобритании. – Allen4Tech
@ Allen4Tech: Я обновил ответ. – Dennis