Home > View Post

Making the ScrollViewerThumbnail interactive

In the last post we took the simple ScrollViewer thumbnail and controllerized it. This time, we're going to make it interactive.

And, because WPF totally rocks, it's stupidly easy to do.

Normally, we'd do lots of mouse capture, remember the original location and the new location to calculate the delta etc etc. With WPF, we can simply use the Thumb control that fires a DragDelta event if the user makes a drag gesture over the control. Huzzah.

So, we need to quickly change the ScrollViewerThumbnail's template in Generic.xaml to look like this:

<ControlTemplate TargetType="{x:Type Controls:ScrollViewerThumbnail}">
    <Viewbox DataContext="{TemplateBinding ScrollViewer}" Stretch="Uniform">
                Width="{Binding Content.ActualWidth}"
                Height="{Binding Content.ActualHeight}">
                    <VisualBrush Visual="{Binding Content}" />
            <Thumb Name="PART_Highlight"
                Background="{TemplateBinding HighlightFill}"
                Width="{Binding ViewportWidth}"
                Height="{Binding ViewportHeight}"
                        X="{Binding HorizontalOffset}"
                        Y="{Binding VerticalOffset}" />
                    <ControlTemplate TargetType="Thumb">
                        <Border Background="{TemplateBinding Background}" />

Note that we've changed the highlight from a Border to a Thumb. We've named it PART_Highlight and I've given the thumb a ControlTemplate that is a simple Border (Thumbs can't have content).

Next, we need to find the PART_Highlight in our ScrollViewerThumbnail template and attach a handler to it's DragDelta event. We can't just use this.FindName("PART_Highlight") because it's part of a template. We have to override the OnApplyTemplate method of the ScrollViewerThumbnail class and use this.Template.FindName("PART_Highlight"):

private const string PART_Highlight = "PART_Highlight";

public override void OnApplyTemplate()

    var partHighlight = (Thumb)this.Template.FindName(PART_Highlight, this);
    partHighlight.DragDelta += partHighlight_DragDelta;

Next, we need to move the ScrollViewer when the DragDelta event occurs.

void partHighlight_DragDelta(object sender, DragDeltaEventArgs e)
    ScrollViewer.ScrollToVerticalOffset(ScrollViewer.VerticalOffset + e.VerticalChange);
    ScrollViewer.ScrollToHorizontalOffset(ScrollViewer.HorizontalOffset + e.HorizontalChange);

And we're done. Seriously! I'm blown away that this can be achieved with just four-ish lines of code.

I've uploaded an example (ClickOnce deployed that you can play with).... get it here:

>>> Download ClickOnce Demo <<<


Just click on the Arrows icon to display a popup showing the ScrollViewer thumbnail.

PS - you can use the mouse wheel to change the size of the ScrollViewerThumbnail control too.

Tags: WPF

Josh Post By Josh Twist
11:56 AM
04 Dec 2008

» Next Post: My new favourite Resharper features
« Previous Post: Controllerizing the ScrollViewer Thumbnail

Comments are closed for this post.

Posted by Markenzie @ 21 Dec 2008 3:25 PM
I have got "WPF ScrollViewer Thumbnail" and "Controllerizing the ScrollViewer Thumbnail" to work fine for me. But I am NOT getting this ("Making the ScrollViewerThumbnail interactive") to work. First I got this error "All objects added to an IDictionary must have a Key attribute or some other type of key associated with them" with the Generic.xaml file and I inserted a x:Key="xxx" and that removed the error.
The program runs without error but I cannot get the thumbnail to show as in the previous 2 posts. Only the scrollviewer shows. Please help OR you can also send me the code of the Clickonce demo here.

Thanks a lot for this post.

Posted by Josh Twist @ 22 Dec 2008 5:06 AM
Hi Markenzie,

Does this help?


I'm happy to post the code if not.


Posted by Markenzie @ 25 Dec 2008 8:23 AM
Thanks a lot Josh. I got it to work. Your post
"Reflectorizing a ClickOnce app" was very, very helpful. Thanks a million and Happy Christmas


Posted by Dennis @ 10 Nov 2011 12:04 PM
Hi Josh, thank you for sharing this great and smart control. The ClickOnce demo doesn't work. It reports "Application cannot be started.". Is it possible for you to post the code? Thanks in advance.

Posted by Josh @ 10 Nov 2011 5:45 PM
Hi Dennis,

Do you have .NET installed - I just stried it on a virgin machine and it worked fine. Also, there is a link above that shows how to tear apart a clickonce app - I'm afriad I don't have the code any longer :(.


© 2005 - 2022 Josh Twist - All Rights Reserved.