自动刷新ICollectionView过滤器

时间:2013-07-18 23:59:36

标签: c# wpf icollectionview

有没有办法自动更新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的洞察力的人。在这一点上,我对任何想法持开放态度。

2 个答案:

答案 0 :(得分:18)

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 ,则可以按照here所述ICollectionViewLiveShaping实施。

我已在此处发布了您的问题的实施部分 - Implementing 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;
}

答案 1 :(得分:10)

对于 .Net 4.5: 有一个 new 界面可以帮助实现此功能,名为: ICollectionViewLiveShaping

来自MSDN link

  

启用实时排序,分组或过滤时,CollectionView   将重新排列CollectionView中数据的位置   数据被修改。例如,假设应用程序使用a   DataGrid列出股票市场中的股票,股票按照排序   股票价值。如果在股票的CollectionView上启用了实时排序,   当股票的价值时,股票在DataGrid中的位置会移动   变得大于或小于另一股票的价值。

以上界面的更多信息: http://www.jonathanantoine.com/2011/10/05/wpf-4-5-%E2%80%93-part-10-live-shaping/


对于 .Net 4及以下: 还有另一篇关于SO QA的帖子可能对您有所帮助: CollectionViewSource Filter not refreshed when Source is changed