WPF 中的 ListBox、VirtualizingStackPanel 和平滑滚动
Posted
技术标签:
【中文标题】WPF 中的 ListBox、VirtualizingStackPanel 和平滑滚动【英文标题】:ListBox, VirtualizingStackPanel, and Smooth Scrolling in WPF 【发布时间】:2010-12-27 19:14:22 【问题描述】:我有一个ListBox
,它可能有很多行模板化数据库记录,包括绑定到ObservableCollection<MyItem>
的Image
。有时集合可以容纳数千件物品。
性能很棒,但滚动是默认的跳跃行为。我希望它有平滑滚动,所以我取消选中ScrollViewer.CanContentScroll
。
现在我可以平滑滚动,但性能很糟糕:数据在单独的线程中检索,线程很快完成,但结果显示在ListBox
中需要 10-20 秒。我认为这是因为取消选中ScrollViewer.CanContentScroll
会将底层VirtualizingStackPanel
更改为常规StackPanel
,因此它会在显示结果之前加载整个集合。
所以我的问题是:如何在不牺牲VirtualizingStackPanel
行为和性能的情况下保持平滑滚动?
【问题讨论】:
如果您准备使用一些小技巧,您可以同时拥有平滑滚动和虚拟化。有关详细信息,请参阅 this answer 到类似问题。 ***.com/questions/1977929/… VirtualizingPanel.ScrollUnit="Pixel" 【参考方案1】:当您取消选中 CanContentScroll 时,您是 lose virtualization。答案确实令人沮丧:目前还没有开箱即用的解决方案:(。
PS:这里不是第一次发帖,问this very question。
【讨论】:
我很害怕,但不得不问。我在问之前搜索过,但没有找到那个帖子。我可能会再挖掘一点,但时间有限,所以我现在不得不失去平滑滚动。【参考方案2】:如果您使用 .NET 4.5(或 4.0,如果您愿意破解一下),那么答案是 over here。
[请注意,@Guilluame 的评论在此答案之前就在这里,但在浏览答案时并不是特别明显。]
【讨论】:
【参考方案3】:对于在 2021 年进行搜索的任何人,您都可以使用以下解决方案:
您将同时保持滚动和虚拟化
<ItemsControl x:Name="TestIC" Grid.Row="1"
ScrollViewer.CanContentScroll="True"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<Border
Padding="TemplateBinding Control.Padding"
Background="TemplateBinding Panel.Background"
BorderBrush="TemplateBinding Border.BorderBrush"
BorderThickness="TemplateBinding Border.BorderThickness"
SnapsToDevicePixels="True">
<ScrollViewer Padding="TemplateBinding Control.Padding" Focusable="False">
<ItemsPresenter SnapsToDevicePixels="TemplateBinding UIElement.SnapsToDevicePixels" />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
【讨论】:
以上是关于WPF 中的 ListBox、VirtualizingStackPanel 和平滑滚动的主要内容,如果未能解决你的问题,请参考以下文章