WPF Tips n' Tricks – Smooth(er) scrolling
A common request with ListViews and other scrollable components is to have a smoother scrolling. By default, when a scrollable control contains items that control their own scrolling, it jumps from one item to the other, by the whole item height. It's not smooth because it's not animated, a step back in usability that I still cannot explain (lack of time maybe?)
The culprits are mainly the Panels like StackPanel and ScrollContentPresenter that don't implement smooth scrolling animations. While changing their behavior to support smooth animation is a way to solve the issue, and it may well be that I start implementing it for a future Tips'n'Tricks, but for now it's out of scope for this entry.
So how to prevent this jumpy behavior? Don't let the content decide how it's going to scroll! It's very easily accomplished, by adding the ScrollViewer.CanContentScroll attached property and setting it to false. Here's a small example:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Smooth Scrolling Demo" Height="300" Width="300">
<Grid>
<ListBox ScrollViewer.CanContentScroll="False">
<ListBox.Items>
<TextBlock Height="40">Text1</TextBlock>
<TextBlock Height="40">Text2</TextBlock>
<TextBlock Height="40">Text3</TextBlock>
<TextBlock Height="40">Text4</TextBlock>
<TextBlock Height="40">Text5</TextBlock>
<TextBlock Height="40">Text6</TextBlock>
<TextBlock Height="40">Text7</TextBlock>
<TextBlock Height="40">Text8</TextBlock>
<TextBlock Height="40">Text9</TextBlock>
<TextBlock Height="40">Text10</TextBlock>
</ListBox.Items>
</ListBox>
</Grid>
</Window>
[Update]
Ronan is absolutely correct in pointing out in my comments:
There's a drawback when using this trick: when ScrollViewer.CanContentScroll is set you loose default scrolling behaviour of the ListBox which uses a VirtualStackPanel. On big collections you will notice a great performance degradation.
This is a complete oversight in this tips'n'tricks. Virtualization means that only visible items within a list will be created and added to the visual tree. Not an issue for a few items, but when you reach the hundreds or thousands, it becomes a necessity. When you set the CanContentScroll property, the virtualizing stack panel stops virtualizing and renders everything. Be aware of that!
And as is also pointed in that comment, making a smooth scrolling *virtualizing* panel is even harder.