wpf 自动刷新 ICollectionView 过滤器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17735994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:14:20  来源:igfitidea点击:

Automatically refresh ICollectionView Filter

c#wpficollectionview

提问by Jason D

Is there any way to automatically update a filter on an ICollectionViewwithout having to call Refresh()when a relevant change has been made?

有没有什么方法可以在进行相关更改时自动更新过滤器ICollectionView而无需调用Refresh()

I have the following:

我有以下几点:

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

The [Notify] attribute in this property just implements INotifyPropertyChangedbut it doesn't seem to be doing anything in this situation.

该属性中的 [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;
    };

In XAML:

在 XAML 中:

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

Update:It looks like using ICollectionViewis going to be necessary for me, so I'd like to revisit this topic. I'm adding a bounty to this question, the recipient of which will be any person who can provide some insight on how to implement a 'hands-off' ICollectionViewthat doesn't need to be manually refreshed. At this point I'm open to any ideas.

更新:看起来使用ICollectionView对我来说是必要的,所以我想重新讨论这个话题。我正在为这个问题添加一个赏金,接收者将是任何可以就如何实现ICollectionView不需要手动刷新的“放手”提供一些见解的人。在这一点上,我愿意接受任何想法。

回答by Rohit Vats

AFAIK there is no inbuilt support in ICollectionViewto refresh collection on any property change in underlying source collection.

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

But you can subclass ListCollectionViewto give it your own implementation to refresh collection on any property changed. Sample -

但是您可以子类化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();
            }
        }
    }
}

You can use this in your project like this -

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

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

This can be reused across your project without having to worry to refresh collection on every PropertyChanged. MyCollectionViewwill do that automaticallyfor you.

这可以在您的项目中重复使用,而不必担心在每个PropertyChanged. MyCollectionViewautomatically为你做的。

OR

或者

If you are using .Net4.5you can go with ICollectionViewLiveShapingimplementation as described here.

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

I have posted the implementation part for your problem here - Implementing ICollectionViewLiveShaping.

我已经在这里发布了您的问题的实施部分 -实施 ICollectionViewLiveShaping

Working code from that post -

该帖子中的工作代码 -

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;
}

回答by VS1

For .Net 4.5:There is a newinterface which can help to achieve this feature, called : ICollectionViewLiveShaping.

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

From MSDN link:

MSDN 链接

When live sorting, grouping, or filtering is enabled, a CollectionView will rearrange the position of data in the CollectionView when the data is modified. For example, suppose that an application uses a DataGrid to list stocks in a stock market and the stocks are sorted by stock value. If live sorting is enabled on the stocks' CollectionView, a stock's position in the DataGrid moves when the value of the stock becomes greater or less than another stock's value.

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

More Info on above interface: http://www.jonathanantoine.com/2011/10/05/wpf-4-5-%E2%80%93-part-10-live-shaping/

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



For .Net 4 and lower: There is also another post on SO QA which might help you: CollectionViewSource Filter not refreshed when Source is changed

对于.Net 4 及更低版本:SO QA 上还有另一篇文章可能对您有所帮助: 更改源时不刷新 CollectionViewSource 过滤器