自动刷新ICollectionView筛选器

本文关键字:筛选 ICollectionView 刷新 | 更新日期: 2023-09-27 18:24:01

是否有任何方法可以在进行相关更改时自动更新ICollectionView上的筛选器,而无需调用Refresh()

我有以下内容:

[Notify]
public ICollectionView Workers { get; set; }

该属性中的[Notify]属性只实现了INotifyPropertyChanged,但在这种情况下似乎没有任何作用。

Workers = new CollectionViewSource { Source = DataManager.Data.Workers }.View;
Workers.Filter = w =>
    {
        Worker worker = w as Worker;
        if (w == null)
            return false;
        return worker.Employer == this;
    };

在XAML中:

<TextBlock x:Name="WorkersTextBlock"
           DataContext="{Binding PlayerGuild}"
           FontFamily="Pericles"
           Text="{Binding Workers.Count,
                          StringFormat=Workers : {0},
                          FallbackValue=Workers : 99}" />

更新:看起来使用ICollectionView对我来说是必要的,所以我想重新讨论这个主题。我为这个问题添加了一个奖励,任何人都可以提供一些关于如何实现不需要手动刷新的"放手"ICollectionView的见解。在这一点上,我对任何想法都持开放态度。

自动刷新ICollectionView筛选器

AFAIK在ICollectionView中没有内置的支持,可以在底层源集合中的任何属性更改时刷新集合。

但是,您可以将ListCollectionView子类化,以便为refresh collection on any property changed提供自己的实现。样品-

public class MyCollectionView : ListCollectionView
{
    public MyCollectionView(IList sourceCollection) : base(sourceCollection)
    {
        foreach (var item in sourceCollection)
        {
            if (item is INotifyPropertyChanged)
            {
                ((INotifyPropertyChanged)item).PropertyChanged +=
                                                  (s, e) => Refresh();
            }
        }
    }
}

你可以像这样在你的项目中使用这个-

Workers = new MyCollectionView(DataManager.Data.Workers);

这可以在整个项目中重复使用,而不必担心在每个PropertyChanged上刷新集合。MyCollectionView会为你做automatically

如果您使用.Net4.5,您可以按照此处所述使用ICollectionViewLiveShaping实现。

我已经在这里发布了你的问题的实现部分——实现ICollectionViewLiveShaping。

那篇文章的工作代码-

public ICollectionViewLiveShaping WorkersEmployed { get; set; }
ICollectionView workersCV = new CollectionViewSource
                         { Source = GameContainer.Game.Workers }.View;
ApplyFilter(workersCV);
WorkersEmployed = workersCV as ICollectionViewLiveShaping;
if (WorkersEmployed.CanChangeLiveFiltering)
{
    WorkersEmployed.LiveFilteringProperties.Add("EmployerID");
    WorkersEmployed.IsLiveFiltering = true;
}

对于.Net 4.5:有一个新的接口可以帮助实现此功能,称为:ICollectionViewLiveShaping

来自MSDN链接:

启用实时排序、分组或筛选时,CollectionView当数据被修改。例如,假设应用程序使用DataGrid列出股票市场中的股票,股票按股票价值。如果在股票的CollectionView上启用了实时排序,当股票价值发生变化时,股票在DataGrid中的位置发生变化变得大于或小于另一只股票的价值。

以上界面的详细信息:http://www.jonathanantoine.com/2011/10/05/wpf-4-5-%E2%80%93-第10部分-成型/


对于.Net 4及更低版本:还有另一篇关于SO QA的帖子可能会对您有所帮助:更改Source时CollectionViewSource筛选器未刷新