C# 自动刷新ICollectionView过滤器

C# 自动刷新ICollectionView过滤器,c#,wpf,icollectionview,C#,Wpf,Icollectionview,是否有任何方法可以自动更新ICollectionView上的过滤器,而无需在进行相关更改时调用Refresh() 我有以下资料: [Notify] public ICollectionView Workers { get; set; } 此属性中的[Notify]属性只实现了INotifyPropertyChanged,但在这种情况下它似乎没有做任何事情 Workers = new CollectionViewSource { Source = DataManager.Data.Workers

是否有任何方法可以自动更新
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的见解的人。在这一点上,我愿意接受任何想法。

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

发件人:

启用实时排序、分组或筛选时,CollectionView 当 数据被修改。例如,假设应用程序使用 DataGrid列出股票市场中的股票,并按 股票价值。如果在stocks的CollectionView上启用了实时排序, 股票在数据网格中的位置随着股票价值的变化而变化 变得大于或小于其他股票的价值

有关上述界面的更多信息:


对于.Net 4及更低版本的: 还有一个关于SO QA的帖子可能会对您有所帮助:

AFAIK
ICollectionView
中没有内置的支持,可以根据基础源集合中的任何属性更改刷新集合

但是,您可以将
ListCollectionView
子类化,为它提供自己的实现,以便
在任何更改的属性上刷新集合
。样品-

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);
这可以在整个项目中重用,而无需担心刷新每个
属性更改的集合
MyCollectionView
将自动为您执行该操作

如果您使用的是.Net4.5,则可以使用所述的
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;
}

好吧,考虑到这个属性不是BCL,它不包括这个角落的情况也就不足为奇了。事实上,WPF中没有任何内容涵盖这个案例,所以您必须自己做。筛选器属性不是DP,即使它是DP,筛选器中的任何内容都不会触发更新事件。看起来你必须手动触发它。也许在过滤器的主体中?您可以通过闭包进行自我引用。查看lambda,您必须将刷新调用卸载到调度程序,以便在应用过滤器后运行它。因此,添加一个bool“brb updateing”块(没有更多的字符)看起来没有任何方法可以绕过它,除了可能在过滤器期间扩展CV和更新,并进行检查以确保不会持续触发更新。有道理为什么那不是BCL,对吧?过滤器会触发一个更新,这会触发一个过滤器,然后不断地…谢谢你的解释。看来我要手动完成了。好吧,抱着希望吧。我将根据历史和我的经验。如果它还没有接线,那么通常你必须自己接线。如果你这样做了,请在下面添加答案,并给自己一些道具!而且,如果你成功了,我会再次让你+1。我对编程相当陌生,在这一点上,我不知道如何用我有限的知识来实现这一点。也许有一天,但还没有。如果你能帮我把这件事做好,赏金肯定会给你的。我在这里发布了一个关于实现
ICollectionViewLiveShaping
的问题:嗯,有点。将新项添加到集合时,由于该逻辑位于构造函数中,因此无法正确处理该项。我将仔细研究一下,看看我能做些什么。实际上,
ICollectionViewLiveShaping
的这个实现也很有效。我不知道当我尝试你的答案时,我一开始做错了什么。再次感谢!如何侦听嵌套属性?仅供参考:您不需要公开
ICollectionViewLiveShaping
,只需保留
ICollectionView
,它仍然可以工作。只要对它进行强制转换并设置属性,它就会工作。