基本上,我有2个ListView,每个都绑定到不同的ItemsSource
。
列表1 无法更改(它是ReadOnlyObservableCollection
)
列表2 可以更改(通过用户交互)。
我需要在List 1中添加一个过滤器,这样它就不会显示List 2中的任何内容。这是我到目前为止的代码......
view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
view.Filter += o =>
{
MyItem item = o as MyItem;
return List2.ItemsSource.??;
};
<小时/> List2.ItemsSource以IEnumerable而不是ObservableCollection(实际上是什么)的形式返回。我想尽可能高效地做到这一点,所以我不确定是否应该:
更新:
第一次呈现后似乎没有继续过滤项目:
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.
};
更新2:
我想我明白为什么它没有重新应用过滤器。原始集合不会引发CollectionChanged通知,因此它不会再次运行过滤器。也许解决这一部分更适合作为一个不同的问题?但是,如果有人想在这里回答:
如何在List2集合更改时让我的List1重新应用过滤器?
更新3: 我问如何在separate SO question中加入collectionchanged事件并得到我的回答。
答案 0 :(得分:1)
ItemsSource
被静态声明为IEnumerable
,但其实际运行时类型可以是实现IEnumerable
的任何内容。如果您碰巧知道它实际上是ObservableCollection<MyItem>
,您可以转换为此类型:
view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
view.Filter += o =>
{
MyItem item = (MyItem)o;
var collection = (ObservableCollection<MyItem>)List2.ItemsSource;
return collection.Contains(item);
};
(或者您可以转换为IList<MyItem>
,因为此界面中定义了Contains
)
Linq也是一个不错的选择:
view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
view.Filter += o =>
{
MyItem item = (MyItem)o;
return List2.ItemsSource.Cast<MyItem>().Contains(item);
};