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?

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. Commented Mar 26, 2012 at 16:34
  • 8
    stackoverflow.com/questions/1977929/… VirtualizingPanel.ScrollUnit="Pixel" Commented Nov 20, 2012 at 13:09

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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

Comments

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>

2 Comments

Not a ListBox, so no selection option here. :(
I'm not great at WPF. But doesn't all the VirtualisingPanel.XXX in the ItemControl node duplicate the properties set on the virtualisingstackpanel?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.