2015-12-29 2 views
2

My Model:Как создать мульти-фильтры для коллекции

public class Person 
{ 
    public string Name { get; set; } 
    public bool Sex { get; set; } 
    public string Country { get; set; } 
} 

В моем приложении WPF, я хочу, чтобы привязать список к DataGridControl, вид также поддерживает фильтр по полу и стране.

Мое текущее решение - создание списка PersonList для хранения всех данных и создания другого списка PersonBindingList для хранения данных, которые должны отображаться в пользовательском интерфейсе. Когда пользователь проверяет фильтры и нажимает «ОК», используя Linq для запроса из PersonList и присваивания результата PersonBindingList для обновления пользовательского интерфейса.

Но это должно содержать два списка. Кроме того, я не хочу загружать данные каждый раз, когда пользователь меняет условия фильтра, поскольку данные volumne очень велики, скорость загрузки очень медленная. Есть ли другие решения? Еще одна вещь: «Секс и страна» могут быть свободными.

Благодаря

ответ

2

Если вы хотите, чтобы фильтровать данные на стороне клиента, 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

Если вы хотите множественного выбора страны из списка фильтрации, вы можете заменить скалярное CountryCountries свойство сбора и переписать логику фильтрации. Что-то вроде этого:

// 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... 
} 
+0

Привет @Dennis, спасибо вам ответ. В вашем коде Sex и Country являются двумя свойствами в ViewModel, если мой фильтр поддерживает множественный выбор, где я должен вызвать метод Refresh? Например, я хочу показать мужчин в США и Великобритании. – Allen4Tech

+0

@ Allen4Tech: Я обновил ответ. – Dennis

Смежные вопросы