编辑以解决F Ruffell's answer
我有以下xaml
<StackPanel>
<ListBox x:Name="_list1"/>
<ListBox x:Name="_list2"/>
</StackPanel>
以及以下代码:
var ints = new[] { 1, 2, 3 };
_list1.ItemsSource = ints;
_list2.ItemsSource = ints;
_list1.Items.Filter = i => ((int)i) < 2;
由于某些原因,仅对第一个
ListBox
设置了过滤器之后,两个列表都被过滤了。我希望列表具有完全不同的CollectionViews
和确实_list1.Items != _list2.Items
。同时,将过滤器设置为其中一个还可以将该过滤器设置为另一个。问题是,为什么和如何同步
CollectionViews
? 最佳答案
它们是同步的,因为即使两个ListBoxes
具有不同的Items
,它们也共享相同的CollectionView
,这是源集合的默认 View 。Items
的ItemsControl
属性的类型为ItemCollection
,而CollectionView
的ItemCollection
属性是内部的,因此我们无法直接访问它以验证这是正确的。但是,我们只需要在调试器中输入这三个值即可进行验证,它们全部为true
_list1.Items.CollectionView == _list2.Items.CollectionView // true
_list1.Items.CollectionView == CollectionViewSource.GetDefaultView(ints) // true
_list2.Items.CollectionView == CollectionViewSource.GetDefaultView(ints) // true
另外,我们可以使用反射在代码中进行比较
PropertyInfo collectionViewProperty =
typeof(ItemCollection).GetProperty("CollectionView", BindingFlags.NonPublic | BindingFlags.Instance);
ListCollectionView list1CollectionView = collectionViewProperty.GetValue(_list1.Items, null) as ListCollectionView;
ListCollectionView list2CollectionView = collectionViewProperty.GetValue(_list2.Items, null) as ListCollectionView;
ListCollectionView defaultCollectionView = CollectionViewSource.GetDefaultView(ints) as ListCollectionView;
Debug.WriteLine(list1CollectionView == list2CollectionView);
Debug.WriteLine(list1CollectionView == defaultCollectionView);
Debug.WriteLine(list2CollectionView == defaultCollectionView);
解决该问题的方法已经由F Ruffell发布,为每个
ListCollectionView
创建一个新的ItemsSource
作为ListBox
。_list1.ItemsSource = new ListCollectionView(ints);
_list2.ItemsSource = new ListCollectionView(ints);
另请注意,此后,上面的3个比较为假
关于.net - WPF ListBoxes的ItemsSource奇怪的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7713688/