自动刷新ICollectionView过滤器

Jas*_*n D 16 c# wpf icollectionview

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

我有以下内容:

[Notify]
public ICollectionView Workers { get; set; }
Run Code Online (Sandbox Code Playgroud)

此属性中的[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;
    };
Run Code Online (Sandbox Code Playgroud)

在XAML中:

<TextBlock x:Name="WorkersTextBlock"
           DataContext="{Binding PlayerGuild}"
           FontFamily="Pericles"
           Text="{Binding Workers.Count,
                          StringFormat=Workers : {0},
                          FallbackValue=Workers : 99}" />
Run Code Online (Sandbox Code Playgroud)

更新:看起来使用ICollectionView对我来说是必要的,所以我想重新审视这个主题.我正在为这个问题添加一笔赏金,其收件人将是任何能够提供有关如何实现ICollectionView不需要手动刷新的"不干涉"的洞察力的人.在这一点上,我对任何想法持开放态度.

Roh*_*ats 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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Workers = new MyCollectionView(DataManager.Data.Workers);
Run Code Online (Sandbox Code Playgroud)

这可以在您的项目中重复使用,而不必担心每次刷新集合PropertyChanged.MyCollectionViewautomatically为你做那件事.

要么

如果您使用的是.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;
}
Run Code Online (Sandbox Code Playgroud)


VS1*_*VS1 10

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

来自MSDN链接:

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

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


对于.Net 4及更低版本:SO QA上还有另一篇文章可能会对您有所帮助: 当Source被更改时,CollectionViewSource Filter不会刷新