gpt4 book ai didi

wpf - 过滤可观察的集合

转载 作者:行者123 更新时间:2023-12-02 20:39:36 25 4
gpt4 key购买 nike

我有一个 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 绑定(bind)到集合。

// 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)。但它确实有效。

但是,项目状态确实会发生变化,例如,如果未选中“完成”,则当项目进入“完成”状态时,应将其从 View 中删除。显然,除非我再次调用 UpdateView,否则这不会改变。所以每次发生变化时我都需要调用这个方法。对我来说这看起来很丑陋而且效率低下。

所以我的问题是,可以用更好的方式来完成吗?

最佳答案

通过创建属性将您的 ListView 直接绑定(bind)到过滤后的集合而不是 ObservableCollection -

public ICollectionView YourFilteredCollection
{
get
{
var source = CollectionViewSource.GetDefaultView(collection.Collection);
source.Filter = p => Filter((ProjectViewModel)p);
return source;
}
}

所以,现在您只需在复选框状态更改事件上对集合调用 Refresh(),如下所示 -

YourFilteredCollection.Refresh();

要根据项类中的任何状态更改刷新集合,您可以通过 Hook 项类的 PropertyChanged 事件来概括它(为此,您的类需要实现 INotifyPropertyChanged)并从那里开始你可以像这样调用刷新 -

foreach (YourClass item in collection.Collection)
{
item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
}

void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
YourFilteredCollection.Refresh();
}

因此,每当您的项目类中的任何属性发生更改时,您的集合都会被过滤。

关于wpf - 过滤可观察的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9615891/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com