WPF ListBox 显示重复项。如何四处走动?
Posted
技术标签:
【中文标题】WPF ListBox 显示重复项。如何四处走动?【英文标题】:WPF ListBox displays duplicate items. How to get around? 【发布时间】:2011-10-17 05:53:25 【问题描述】:我有一个 ListBox,里面有一个嵌套的 ListBox。两者都将 ObservableCollections 作为其 ItemsSource 集,内部 ListBox 的集合是外部对象的成员...
集合由一个从网络服务收集数据的 BackgroundWorker 填充。我必须从 ObservableCollection 更改为 AsyncObservableCollection 才能从工作人员的代码中添加项目。 AsyncObservableCollection 代码来自这里:Have worker thread update ObservableCollection that is bound to a ListCollectionView
我的问题是内部 ListBox 不断显示重复项。如果它决定复制,它似乎总是复制第一个项目。我不知道为什么会这样。通过附加到集合的 CollectionChanged 事件的事件侦听器,我发现每个项目都会触发一次该事件。
你有什么想法吗?
谢谢, 斯蒂芬
【问题讨论】:
你将不得不在这里给我们一些更多的细节。尝试将您的代码缩减为仍然存在此问题的最小示例,然后更新您的问题以包含所有代码。 不幸的是,我无法在一个小示例中重现该行为。除此之外,我不允许将我的代码发布到网上,所以我想我必须自己处理这个问题。感谢所有愿意提供帮助的人;) 【参考方案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>
【讨论】:
【参考方案2】:前几天我的自定义INotifyCollectionChanged
集合和TreeView
也遇到了同样的问题。我花了几个小时的调试才弄清楚主要问题是什么。由于我在网络上没有找到任何导致这种行为的原因的信息,所以我决定在这里分享我的结果。
这种行为的根本原因显然是底层的CollectionView
负责处理ItemsControl
控件中的集合引发的CollectionChanged
事件,不仅仅依赖于NotifyCollectionChangedEventArgs
实例提供的信息更新用户界面。它还考虑了收到通知时集合的内容。
考虑对集合执行以下操作:
-
清除集合(不引发
CollectionChanged
)
将项目 A 添加到集合中(不引发 CollectionChanged
)
引发CollectionChanged
事件以清除在步骤 1 中执行的操作 (NotifyCollectionChangedEventArgs.Action = NotifyCollectionChangedAction.Reset
)
为步骤 2 中执行的添加操作引发 CollectionChanged
事件 (NotifyCollectionChangedEventArgs.Action = NotifyCollectionChangedAction.Add
)
这样做会使项目 A 在 UI 中出现两次。原因是当CollectionView
收到第一个CollectionChanged
通知时(步骤3),它不关心事件args 的Action
是否为Reset
,它查看集合并看到有一个集合中的项目。所以它将项目添加到控件中。然后当它收到第二个通知(第 4 步)时,它认为一个新项目已添加到集合中并再次将该项目添加到控件中!
我不确定这种行为是否在意料之中,但确实存在。
【讨论】:
【参考方案3】:我发现 AsyncObservableCollection 导致了这些问题。显然它搞砸了一些事件或其他什么。 我最终在工作人员的 ProgressChanged 方法中将项目添加到集合中。
【讨论】:
你能再解释一下吗?我有同样的问题。顺便说一句,这似乎是一个时间问题(如果我在向 AsyncObservableCollection 添加内容时等待 100 毫秒,则没有幽灵项目。奇怪 - 无论如何,我没有得到你的解决方案,你能解释一下吗?你放弃了 AsyncObservableCollection 吗?以上是关于WPF ListBox 显示重复项。如何四处走动?的主要内容,如果未能解决你的问题,请参考以下文章
WPF中ListBox连续选择同一项时SelectionChanged 事件不响应的问题