WPF:ICollectionView-如果项目包含在另一个列表中,是否筛选一个列表?

WPF:ICollectionView-如果项目包含在另一个列表中,是否筛选一个列表?,wpf,listview,filter,itemssource,icollectionview,Wpf,Listview,Filter,Itemssource,Icollectionview,基本上,我有两个ListView,每个都绑定到不同的ItemsSource 无法更改列表1(它是一个ReadOnlyObservableCollection)。 列表2可以更改(通过用户交互)。 我需要在列表1中添加一个过滤器,这样它就不会显示列表2中的任何内容。这是我到目前为止的代码 view = CollectionViewSource.GetDefaultView(List1.ItemsSource); view.Filter += o => { MyItem item =

基本上,我有两个ListView,每个都绑定到不同的
ItemsSource

无法更改列表1(它是一个
ReadOnlyObservableCollection
)。
列表2可以更改(通过用户交互)。

我需要在列表1中添加一个过滤器,这样它就不会显示列表2中的任何内容。这是我到目前为止的代码

view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
view.Filter += o =>
{
    MyItem item = o as MyItem;
    return List2.ItemsSource.??;
};

List2.ItemsSource作为IEnumerable返回,而不是ObservableCollection(它实际上是什么)。我希望尽可能高效地完成这项工作,因此我不确定是否应该:

  • 显式地将ItemsSource强制转换为IList以获得对Contains的访问
  • 遍历ItemsSource我自己查看它是否包含该项
  • 使用LINQ的强制转换扩展方法强制转换到IList(或其他类型)以获得对Contains的访问权
  • 还有别的办法吗

  • 更新:

    在第一次渲染后,它似乎不会继续过滤项目:

    view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
    view.Filter += o =>
    {
        MyItem item = (MyItem)o;
        var collection = (ObservableCollection<MyItem>)List2.ItemsSource;
        //return collection.Contains(item);//Filters out ALL items from the list
        return !collection.Contains(item); //Shows all items, but as I add items
                                           //to list 2 it doesn't filter items out of
                                           //list 1.
    };
    
    view=CollectionViewSource.GetDefaultView(List1.ItemsSource);
    view.Filter+=o=>
    {
    MyItem项目=(MyItem)o;
    var集合=(ObservableCollection)List2.ItemsSource;
    //return collection.Contains(item);//从列表中筛选出所有项
    return!collection.Contains(item);//显示所有项目,但在添加项目时
    //要列出2,它不会从列表中筛选项目
    //清单1。
    };
    
    更新2:

    我想我理解为什么它不重新应用过滤器。原始集合没有引发CollectionChanged通知,因此它不需要再次运行筛选器。也许解决这一部分更适合作为一个不同的问题?但是,如果有人想在这里回答:

    当List2集合更改时,如何让我的List1重新应用筛选器

    更新3:
    我问了如何与a中的collectionchanged事件关联,并得到了我的答案。

    ItemsSource
    静态声明为
    IEnumerable
    ,但其实际运行时类型可以是实现
    IEnumerable
    的任何东西。如果您碰巧知道它实际上是一个
    可观察集合
    ,则可以强制转换为以下类型:

    view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
    view.Filter += o =>
    {
        MyItem item = (MyItem)o;
        var collection = (ObservableCollection<MyItem>)List2.ItemsSource;
        return collection.Contains(item);
    };
    

    ItemsSource
    静态声明为
    IEnumerable
    ,但其实际运行时类型可以是实现
    IEnumerable
    的任何东西。如果您碰巧知道它实际上是一个
    可观察集合
    ,则可以强制转换为以下类型:

    view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
    view.Filter += o =>
    {
        MyItem item = (MyItem)o;
        var collection = (ObservableCollection<MyItem>)List2.ItemsSource;
        return collection.Contains(item);
    };
    

    是的,两者似乎都能正常工作,但我希望知道哪一个是最好的(最有效的)。事实上,我只是运行了它,我认为它们运行正常,但它似乎没有过滤。很多物品的名字都很接近,所以我以为它们被过滤掉了,但事实并非如此。@michael,没有一个比另一个更好,因为它总是会在列表2上进行线性搜索。第一个选项(cast)可能比第二个选项(Linq.cast/.Contains)稍快一些,但可能不明显当修改List2时过滤器不会自动刷新。您需要重新分配ICollectionView的Filter属性才能显式重新执行筛选器。@托马斯:如何才能做到这一点?是的,两者似乎都能正常工作,但我希望知道哪一个是最好的(最有效的)。实际上,我刚刚运行了它,我以为它们运行正常,但似乎没有进行筛选。很多物品的名字都很接近,所以我以为它们被过滤掉了,但事实并非如此。@michael,没有一个比另一个更好,因为它总是会在列表2上进行线性搜索。第一个选项(cast)可能比第二个选项(Linq.cast/.Contains)稍快一些,但可能不明显当修改List2时过滤器不会自动刷新。您需要重新分配ICollectionView的Filter属性才能显式地重新执行筛选器。@托马斯:如何才能做到这一点?