19

有什么方法可以自动更新过滤器,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不需要手动刷新的“放手”的见解的人。在这一点上,我对任何想法都持开放态度。

4

2 回答 2

21

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. 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;
}
于 2013-07-28T08:34:53.817 回答
11

对于.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 上还有另一篇文章可能对您有所帮助: CollectionViewSource Filter not refreshed when Source is changed

于 2013-07-25T07:23:09.237 回答