У меня есть элемент управления ListView
, который отображает элементы из наблюдаемой коллекции. Эти элементы должны быть отфильтрованы. Я могу сделать это с помощью CollectionViewSource
, но фильтр необходимо обновлять каждый раз при изменении элемента.
Мои элементы выглядят следующим образом:
enum Status {Done, Failed, Skipped, ...}
class Project {
public string Name {get;set;}
public Status Status {get;set;}
// etc. etc.
}
class ProjectViewModel : INotifyPropertyChanged {
private Project project;
public ProjectBuildInfoViewModel(ProjectBuildInfo project)
{
this.project = project;
}
public string Name
{
get { return project.Name; }
set { project.Name = value; OnPropertyChanged("Name"); }
}
// etc. etc.
}
class CollectionViewModel {
private ObservableCollection<ProjectViewModel> projects =
new ObservableCollection<ProjectViewModel>();
public ObservableCollection<ProjectViewModel> Collection
{
get { return projects; }
private set {projects = value; }
}
}
Затем у меня есть ListView
, чей ItemSource
привязан к коллекции.
// member of the user control class
private CollectionViewModel collection = new CollectionViewModel();
// in the constructor
listView.ItemSource = collection.Collection.
Это ничего не фильтрует. Итак, у меня есть эти флажки, и они должны указывать, какие элементы (в зависимости от состояния) должны отображаться.Затем я использовал CollectionViewSource
:
private void UpdateView()
{
var source = CollectionViewSource.GetDefaultView(collection.Collection);
source.Filter = p => Filter((ProjectViewModel)p);
listStatus.ItemsSource = source;
}
Метод фильтрации выглядит следующим образом:
private bool Filter(ProjectViewModel project)
{
return (ckFilterDone.IsChecked.HasValue && ckFilterDone.IsChecked.Value && project.Status == Status.Done) ||
(ckFilterFailed.IsChecked.HasValue && ckFilterFailed.IsChecked.Value && project.Status == Status.Failed) ||
(ckFilterSkipped.IsChecked.HasValue && ckFilterSkipped.IsChecked.Value && project.Status == Status.Skipped);
}
Недостатком этого метода является захват значений флажков, поэтому мне приходится вызывать этот метод ( UpdateView
) каждый раз, когда установлен флажок. Но это работает.
Тем не менее, состояние элемента изменяется, и если, например, не отмечено «готово», то при переходе элемента в состояние «готово» его следует удалить из представления. Очевидно, что это не изменится, если я снова не вызову UpdateView
. Поэтому мне нужно вызывать этот метод каждый раз, когда что-то меняется. Это выглядит некрасиво и неэффективно для меня.
Итак, мой вопрос: можно ли это сделать получше?