WPF ListBoxes的ItemsSource奇怪的行为 [英] Wpf ListBoxes' ItemsSource strange behaviour

查看:42
本文介绍了WPF ListBoxes的ItemsSource奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑以解决 F Ruffell的答案

我有以下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 .同时将filter设置为其中一个还可以以某种方式将该filter设置为另一个.
问题是为什么如何同步 CollectionViews ?

For some reason after setting filter only for the first ListBox both lists are filtered. I expect the lists to have completely different CollectionViews and indeed _list1.Items != _list2.Items. Meanwhile setting filter to one of them also somehow sets that very filter to the other.
The question is why and how are CollectionViews synchronized?

推荐答案

问题是,为什么以及如何同步CollectionViews?

The question is why and how are CollectionViews synchronized?

它们是同步的,因为即使两个 ListBoxes 具有不同的 Items ,它们也共享相同的 CollectionView ,这是源的默认视图集合.

They are synchronized because even though both ListBoxes have different Items, they share the same CollectionView, which is the default view for the source collection.

ItemsControl 的 Items 属性的类型为 ItemCollection ItemCollection 内部,因此我们无法直接访问它以验证这是正确的.但是,我们只需要在调试器中输入这三个值即可进行验证,它们全部显示为真

The Items property of ItemsControl is of type ItemCollection and the CollectionView property of ItemCollection is internal so we can't access it directly to verify that this is true. However, we can just enter these three values in the debugger to verify this, they all come out as true

_list1.Items.CollectionView == _list2.Items.CollectionView // true
_list1.Items.CollectionView == CollectionViewSource.GetDefaultView(ints) // true
_list2.Items.CollectionView == CollectionViewSource.GetDefaultView(ints) // true

或者,我们可以使用反射在代码中进行比较

Alternatively, we can use reflection to do the comparison in code

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 发布,为每个 ListBox创建一个新的 ListCollectionView 作为 ItemsSource .

The way to work around this has already been posted by F Ruffell, create a new ListCollectionView as ItemsSource for each ListBox.

_list1.ItemsSource = new ListCollectionView(ints);
_list2.ItemsSource = new ListCollectionView(ints);

还请注意,此后,上面的3个比较为假

这篇关于WPF ListBoxes的ItemsSource奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆