我有一个带有嵌套ListBox的ListBox。两者都有ObservableCollections作为其ItemsSource设置,内部ListBox的集合是外部对象的成员......
这些集合由BackgroundWorker填充,后者从Web服务收集数据。我不得不从ObservableCollection更改为AsyncObservableCollection,以便能够从worker的代码中添加项目。 AsyncObservableCollection代码来自此处:Have worker thread update ObservableCollection that is bound to a ListCollectionView
我的问题是内部ListBox会一直显示重复的项目。如果它决定复制它似乎总是重复第一个项目。我不知道为什么会这样。通过附加到集合的CollectionChanged事件的事件侦听器,我发现事件每个项目被触发一次。
你有什么想法吗?
谢谢, 斯蒂芬
答案 0 :(得分: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 :(得分:0)
我发现AsyncObservableCollection导致了问题。显然它搞砸了一些事件或其他什么。 我最终在worker的ProgressChanged方法中向集合中添加了项目。
答案 2 :(得分:0)
前几天我的自定义 INotifyCollectionChanged
集合和 TreeView
遇到了同样的问题。我花了几个小时的调试才弄清楚主要问题是什么。由于我在网络上没有找到有关导致这种行为的原因的任何信息,因此我决定在这里分享我的结果。
这种行为的根本原因显然是负责处理由 CollectionView
控件中的集合引发的 CollectionChanged
事件的底层 ItemsControl
并不仅仅依赖于提供的信息通过 NotifyCollectionChangedEventArgs
实例更新 UI。它还考虑了接收通知时的集合内容。
考虑对集合执行以下操作:
CollectionChanged
)CollectionChanged
)CollectionChanged
) 中执行的清除操作引发 NotifyCollectionChangedEventArgs.Action = NotifyCollectionChangedAction.Reset
事件CollectionChanged
) 中执行的添加操作引发 NotifyCollectionChangedEventArgs.Action = NotifyCollectionChangedAction.Add
事件这样做会使项目 A 在用户界面中出现两次。原因是当 CollectionView
收到第一个 CollectionChanged
通知(第 3 步)时,它并不关心事件 args 的 Action
是否为 Reset
,它看起来在集合中,看到集合中有一个项目。所以它将项目添加到控件中。然后当它收到第二个通知(第 4 步)时,它认为集合中添加了一个新项目,并再次将该项目添加到控件中!
我不确定这种行为是否符合预期,但确实存在。