ListBox, VirtualizingStackPanel, and Smooth Scrolling in WPF

21,626

Solution 1

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.

Solution 2

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

Solution 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>
Share:
21,626
Joel Cochran
Author by

Joel Cochran

Long time .NET and Azure developer currently focused on Data platform and process engineering. I lead the technology division for a data analytics and decision sciences firm. MSCIS, JM, ASPInsider. Former Microsoft MVP and Microsoft employee.

Updated on November 24, 2021

Comments

  • Joel Cochran
    Joel Cochran over 2 years

    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?

  • Joel Cochran
    Joel Cochran over 14 years
    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.