Creating a Zoomable ScrollViewer with ZoomSnapPoints in WinRT XAML

The Metro/WinRT XAML ScrollViewer by default allows to zoom in on its contents. That is because its ZoomMode property defaults to “Enabled”. I think in most cases it is actually not the desired behavior and you might want to set ZoomMode to ZoomMode.Disabled. I do understand though that this makes the feature more discoverable and does not hurt much while potentially getting users familiar with the new paradigm of quickly scrolling by zooming that is also displayed in the SemanticZoom control.

For my application I needed to enable users to zoom in on a horizontal StackPanel with a list of buttons so that all the buttons fit on screen. At first I thought I would use the SemanticZoom control, but then I realized I need an actual zoom not a semantic one, so the improved (over WPF/Silverlight) ScrollViewer is an obvious choice.

Since ZoomMode is enabled by default – it would seem that you do not need to do anything but put the StackPanel inside of a ScrollViewer, but I need the ScrollViewer to scroll horizontally, so I need to set Horizontal/Vertical-ScrollBarVisibility and Horizontal/Vertical-ScrollMode:

<ScrollViewer
    ScrollViewer.HorizontalScrollBarVisibility="Auto"
    ScrollViewer.VerticalScrollBarVisibility="Disabled"
    ScrollViewer.HorizontalScrollMode="Enabled"
    ScrollViewer.VerticalScrollMode="Disabled">

Or I can just use the HorizontalScrollViewerStyle style that comes as part of the default StandardStyles resource dictionary and overwrite its default ZoomMode value of Disabled.

<ScrollViewer
    Style="{StaticResource HorizontalScrollViewerStyle}"
    ScrollViewer.ZoomMode="Enabled">

Then I would like to limit the zoom range because by default I can zoom out so that my buttons are just a tiny spot in the middle of the screen or zoom in on a few pixels of my button image – my buttons which are defined using button state images provided for the ImageButton control (part of the WinRT XAML Toolkit). Since I know my view is 1366 pixels wide (it is inside of a Viewbox which scales it to any screen) and the buttons StackPanel is 2470 points wide – I want to limit the zoom factors to be between 1366/2470 and 1:

<ScrollViewer
    Style="{StaticResource HorizontalScrollViewerStyle}"
    ScrollViewer.ZoomMode="Enabled"
    MinZoomFactor="0.5530364"
    MaxZoomFactor="1.0">

That is almost good, but I can still zoom out partly which is not very elegant. No problem – the ScrollViewer has a ZoomSnapPoints property so I can snap to certain zoom factors. The problem is that the property is not very well documented and it does not show up in the XAML editor, so I guess you have to set it in code behind. I am thinking about creating some sort of a converter or attached property for the WinRT XAML Toolkit to be able to define it in XAML, but I am still hoping the final version of Windows 8 will have it solved, so for now I am sticking to the code behind solution. The property is defined as IList, so you need to clear it just in case and add the zoom factor values you want to snap to. I also want to set the ZoomSnapPointsType to Mandatory, so snapping always happens. With that I do not actually need the Min/Max-ZoomFactor properties anymore, although these still do limit the zoom range while touching the control, since snapping only happens when you remove your fingers. Here is the final code:

<ScrollViewer
    x:Name="scrollViewer"
    Style="{StaticResource HorizontalScrollViewerStyle}"
    ScrollViewer.ZoomMode="Enabled"
    ZoomSnapPointsType="Mandatory">
this.scrollViewer.ZoomSnapPoints.Clear();
this.scrollViewer.ZoomSnapPoints.Add(0.5530364f);
this.scrollViewer.ZoomSnapPoints.Add(1.0f);
Advertisements
Tagged , , , ,

3 thoughts on “Creating a Zoomable ScrollViewer with ZoomSnapPoints in WinRT XAML

  1. […] must have a solid understanding of asynchronous JavaScript development and promises…”Creating a Zoomable ScrollViewer with ZoomSnapPoints in WinRT XAML (Filip Skakun)“The Metro/WinRT XAML ScrollViewer by default allows to zoom in on its […]

  2. […] Read original post by Filip Skakun at Xyzzer's Dev Blog […]

  3. sunil kumar sc says:

    Thank u ..helped a lot

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: