WPF 3.5 SP1 Feature: Non-live Scrolling

So far for the new WPF 3.5 SP1 features, I've surveyed Item Container Recycling, Data Formatting, and IEditableCollectionView. Next on my list is Non-live Scrolling!

What is it?

Before 3.5 SP1, the WPF ScrollViewer only supported live scrolling, which means the view of content the ScrollViewer contains updates immediately as the user moves the ScrollBar. For controls like ItemsControl that had large data sets, live scrolling performance often looked sluggish. Now in SP1, app developers have the option to use non-live scrolling. The prime example that many people use to describe this is Outlook. Scroll up and down your list of emails. You’ll notice that the view updates when you have finished scrolling, which is non-live scrolling. I did notice that when you don’t have a large set of emails it does use live scrolling.

How do I use it?

These are the new APIs added to ScrollViewer:

public class ScrollViewer : ContentControl

{

   public static readonly DependencyProperty IsDeferredScrollingEnabledProperty;

   public static bool GetIsDeferredScrollingEnabled(DependencyObject element) { }

   public static void SetIsDeferredScrollingEnabled(DependencyObject element,

                                                        bool value) { }

   public double ContentHorizontalOffset { get; }

   public double ContentVerticalOffset { get; }

}

 

This is opt-in functionality so IsDeferredScrollingEnabled is off by default. ContentHorizontalOffset and ContentVerticalOffset are similar to HorizontalOffset and VerticalOffset except they only update their values to the new offset when the non-live scroll is completed. Also note that when turned on, it will do non-live scrolling in both the horizontal and vertical directions.

Well, that sounds easy enough. I put together a really quick sample that uses non-live scrolling and in addition adds a cell counter to let you know where you are as you scroll. This is similar to Word’s “Page: x of y” functionality.

nonlivescrollingsample

I use a ListView and bind IsDeferredScrollingEnabled to a CheckBox so you can turn it on and off dynamically. The item counter is only visible when non-live scrolling is turned on.

<ListView Name="mylv"

ItemsSource="{Binding Mode=OneWay, Source={StaticResource products}}"

ScrollViewer.IsDeferredScrollingEnabled="{Binding ElementName=myCheckBox, Path=IsChecked}">

Note that IsDeferredScrollingEnabled is an attached property and works with ListView because a ScrollViewer is defined in the ListView's control template. The counter I'm using is bound to a property of the ScrollViewer (VerticalOffset) which I use a converter to show the correct current and total items.

Here is the project which works on the WPF 3.5 SP1 beta bits.

NonLiveScrollingSampleApp.zip