Filtrar uma coleção observável

Eu tenho umListView controle que exibe itens de uma coleção observável. Esses itens precisam ser filtrados. Eu sou capaz de fazer isso com umCollectionViewSource, mas o filtro precisa ser atualizado sempre que um item é alterad

Meus itens ficam assim:

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; }
  } 
}

Então eu tenho esseListView de quemItemSource está vinculado à coleção.

// member of the user control class
private CollectionViewModel collection = new CollectionViewModel();

// in the constructor
listView.ItemSource = collection.Collection.

Isso não filtra nada. Então, eu tenho essas caixas de seleção e elas devem indicar quais itens (dependendo do estado) devem ser exibidos. Eu usei então umCollectionViewSource:

private void UpdateView()
{
  var source = CollectionViewSource.GetDefaultView(collection.Collection);
  source.Filter = p => Filter((ProjectViewModel)p);
  listStatus.ItemsSource = source;
}

O método de filtro é assim:

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);
}

Isso tem a desvantagem de capturar os valores das caixas de seleção, então eu tenho que chamar esse método UpdateView) sempre que uma caixa de seleção estiver marcada. Mas funciona.

No entanto, o estado do item muda e, se "concluído" não estiver marcado, por exemplo, quando um item entra em "pronto", ele deve ser removido da exibição. Obviamente isso não muda, a menos que eu ligue novamente paraUpdateView. Então, eu preciso chamar esse método sempre que algo mudar. Isso me parece feio e ineficient

Então, minha pergunta é: isso pode ser feito de uma maneira melho

questionAnswers(6)

yourAnswerToTheQuestion