WPF ListBox 显示重复项。如何解决?

5
我有一个ListBox,里面嵌套了一个ListBox。两者的ItemsSource都是ObservableCollection,其中内部ListBox的集合是外部对象的成员...

这些集合是由BackgroundWorker填充的,该BackgroundWorker从Web服务中收集数据。我不得不从ObservableCollection更改为AsyncObservableCollection,以便能够在worker的代码中添加项目。 AsyncObservableCollection代码来自于这里:Have worker thread update ObservableCollection that is bound to a ListCollectionView

我的问题是,内部ListBox始终显示重复的项目。如果它决定重复,则似乎总是重复第一个项目。我不知道为什么会发生这种情况。通过将事件侦听器附加到集合的CollectionChanged事件,我发现事件每个项目正常触发一次。

你有任何想法吗?

谢谢, 斯蒂芬


1
你需要提供更多的细节。尝试将你的代码缩减到最小的可能例子,仍然能够展示这个问题,然后更新你的问题并包含所有的代码。 - ColinE
很遗憾,我无法在一个小例子中重现这种行为。除此之外,我不允许将我的代码公开到网络上,所以我想我必须自己解决这个问题。无论如何,感谢所有愿意帮助我的人 ;) - sjanz
3个回答

1
我最近遇到了与我的自定义INotifyCollectionChanged集合和TreeView相同的问题。花费了我几个小时的调试才找出主要问题所在。由于我没有在网上找到任何有关导致此类行为的信息,因此我决定在这里分享我的结果。
这种行为的根本原因是显然负责处理由ItemsControl控件中的集合引发的CollectionChanged事件的基础CollectionView不仅依赖于NotifyCollectionChangedEventArgs实例提供的信息来更新UI,还考虑在接收通知时集合的内容。
请考虑对集合执行以下操作:
  1. 清空集合(不触发CollectionChanged
  2. 将A项添加到集合中(不触发CollectionChanged
  3. 为步骤1执行的Clear操作引发CollectionChanged事件(NotifyCollectionChangedEventArgs.Action = NotifyCollectionChangedAction.Reset
  4. 为步骤2执行的Add操作引发CollectionChanged事件(NotifyCollectionChangedEventArgs.Action = NotifyCollectionChangedAction.Add

这样做将会使A项在UI中出现两次。原因是当CollectionView接收到第一个CollectionChanged通知(步骤3)时,它并不关心事件参数的Action是否为Reset,它查看集合并发现集合中有一项。所以它将该项添加到控件中。然后当它接收到第二个通知(步骤4)时,它认为新项已被添加到集合中,并再次将该项添加到控件中!

我不确定这种行为是否是预期的,但确实存在。


1
如果您将ItemsSource绑定到AsyncObservableCollection,则必须使用VistualizingStackPanel来纠正此问题:
<ListBox
 ItemTemplate="{StaticResource YourItemTemplate}"
 ItemsSource="{Binding Path=YourAsyncObservableCollection}" 
 ScrollViewer.CanContentScroll="False"
 ScrollViewer.HorizontalScrollBarVisibility="Auto"
 ScrollViewer.VerticalScrollBarVisibility="Disabled"
 Style="{DynamicResource YourListBoxStyle}">
 <ListBox.ItemsPanel>
  <ItemsPanelTemplate>
   <VirtualizingStackPanel Orientation="Vertical" />
  </ItemsPanelTemplate>
 </ListBox.ItemsPanel>
</ListBox>

-1

我发现AsyncObservableCollection引起了问题。显然它与某些事件或其他东西搞混了。 最终,我在工作线程的ProgressChanged方法中添加了项目到集合中。


2
你能再解释一下吗?我也有完全相同的问题。似乎是个时间问题(如果我在向AsyncObservableCollection添加内容时等待100毫秒,就没有幽灵项了。奇怪 - 不管怎样,我不明白你的解决方案,能否解释一下?你放弃使用AsyncObservableCollection了吗?) - Werner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接