私には、観察可能なコレクションのアイテムを表示する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; }
}
}
その後、私はそのItemSource
コレクションにバインドされているこのListView
を持っています。
// 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
と呼ぶまでそれは変わらない。だから私は何かが変わるたびにこのメソッドを呼び出す必要があります。それは私には醜く非効率的に見えます。
私の質問は、これはより良い方法で行うことができますか?
私は答えとして別のアプローチを掲載しましたが、Update()を呼び出さずにフィルタを動作させることを思い出しています。 ProjectでNotifyPropertyChangedを実装してみてください。バインディングは、NotifyPropertyChangedなしで変更を認識しません。 – Paparazzi