编辑以解决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 。
ItemsItemsControl属性的类型为ItemCollection,而CollectionViewItemCollection属性是内部的,因此我们无法直接访问它以验证这是正确的。但是,我们只需要在调试器中输入这三个值即可进行验证,它们全部为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/

10-11 19:19