ListBox, VirtualizingStackPanel, and Smooth Scrolling in WPF
Asked Answered
F

3

23

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?

Furtado answered 17/12, 2009 at 19:44 Comment(2)
You can have both smooth scrolling and virtualization if you're prepared to use a little hack. See this answer to a similar question for details.Vadim
#1978429 VirtualizingPanel.ScrollUnit="Pixel"Decompose
W
11

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.

Wyne answered 17/12, 2009 at 20:46 Comment(1)
I was afraid of that but had to ask. I searched before asking but didn't find that post. I might dig just a little bit more, but time is limited so I'll have to lose Smooth Scrolling for now.Furtado
Z
5

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.]

Zarger answered 2/11, 2015 at 13:47 Comment(0)
C
3

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>
Carl answered 23/11, 2021 at 15:2 Comment(2)
Not a ListBox, so no selection option here. :(Headcheese
I'm not great at WPF. But doesn't all the VirtualisingPanel.XXX in the ItemControl node duplicate the properties set on the virtualisingstackpanel?Evelynneven

© 2022 - 2024 — McMap. All rights reserved.