WPF 中的 ListBox、VirtualizingStackPanel 和平滑滚动

发布于 2024-08-15 04:49:16 字数 490 浏览 10 评论 0原文

我有一个 ListBox,它可能包含许多行模板化数据库记录,包括绑定到 ObservableCollectionImage。有时,该收藏可以容纳数千件物品。

性能很棒,但滚动是默认的跳跃行为。我希望它能够平滑滚动,因此我取消选中 ScrollViewer.CanContentScroll

现在我可以平滑滚动,但性能很糟糕:在单独的线程中检索数据,并且线程很快完成,但需要 10-20 秒才能将结果显示在 ListBox 中。我认为这是因为取消选中 ScrollViewer.CanContentScroll 会将底层 VirtualizingStackPanel 更改为常规 StackPanel,因此它会在显示之前加载整个集合结果。

所以我的问题是:如何在不牺牲 VirtualizingStackPanel 行为和性能的情况下保持平滑滚动?

I have a ListBox that may have many rows of templated DB records, including an Image, bound to an ObservableCollection<MyItem>. Sometimes the collection could hold thousands of items.

The performance is great, but the scrolling is the default jumpy behavior. I would like it to have smooth scrolling, so I unchecked ScrollViewer.CanContentScroll.

Now I have smooth scrolling, but the performance is horrendous: the data is retrieved in a separate thread, and the thread finishes quickly, but it takes 10-20 seconds for the results to show in the ListBox. I assume that this is because unchecking ScrollViewer.CanContentScroll changes the underlying VirtualizingStackPanel to a regular StackPanel and so it is loading the entire collection before displaying the results.

So my question is this: how do I retain the the smooth scrolling without sacrificing the VirtualizingStackPanel behavior and performance?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

回忆追雨的时光 2024-08-22 04:49:16

当您取消选中 CanContentScroll 时,您将失去虚拟化。答案确实令人沮丧:目前还没有开箱即用的解决方案:(。

PS:这不是这里的第一篇文章,询问 这个问题

When you uncheck CanContentScroll, you lose virtualization. And the answer is really frustrating: For now there is no out-of-the-box solution :(.

PS: This is not the first post here, asking this very question.

蓦然回首 2024-08-22 04:49:16

如果您使用 .NET 4.5(或者 4.0,如果您愿意破解一点),那么这里有一个答案。

[请注意,@Guilluame 的评论就在这个答案之前,但在浏览答案时并不特别明显。]

If you use .NET 4.5 (or 4.0 if you're willing to hack a bit) then there's an answer over here.

[Note that @Guilluame's comment was here way before this answer but it wasn't particularly visible when skimming for answers.]

多情癖 2024-08-22 04:49:16

对于任何在 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>

For anyone searching at 2021 you can use solution like this:

You will keep scrolling and virtualization at the same time

            <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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文