WinRT / Store App: Stacked content scrolled Horizontally

Ever tried using the ScrollViewer Control for Vertically stacked elements and wanted to scroll only horizontally? Here is a short explanation.

27 March 2014
Christoph Keller Christoph Keller

Introduction

If you want to create a scrolling view in a Windows 8 store app / WinRT App, you need to encapsulate the content using a ScrollViewer XAML control.

But a ScrollViewer is responsible for horizontal and vertical scrolling by default, so it will not limit the width nor the height of the inner content. So a inner stack-panel (or any element who wraps around inner elements) will not be limited in the height and so they will never get to a second column.

Non-working solutions

I spent hours, trying to solve this problem. There are many possible 'solutions' which either have no effect or just don't work. So I created a list of non-working solutions:

  • Setting the height of the ScrollViewer using a bind expression and set it to the height of the outer grid (or grid row / column).
    This will just limit the height of the ScrollViewer itself, so it does not do anything with the inner content.
  • Setting the height of the inner content (for example by using another Grid to encapsulate the content).
    This would work, but setting it to a static value is not a good solution for an app which should work with different resolutions.
  • Adding Grids around the ScrollViewer or inside the ScrollViewer content.
    This just adds another element which will not have any function.

The working solution

Thanks to the blog-post from David Rector, I found out that the solution is just very easy. But it is very tricky as it just depends on a single attribute value of the ScrollViewer which needs to be correct.

We're talking about the property VerticalScrollBarVisibility. If this property is just set to Hidden, the ScrollViewer just thinks 'ah, just hide the scrollbar and I'm fine...' and that's not what we're trying to do.

You need to set the VerticalScrollBarVisibility to Disabled to direct the ScrollViewer that he should not expand the inner content vertically. Here is a short example of the solution:

<Grid>
	<Grid.RowDefinitions>
		<RowDefinition Height="*"/>
	</Grid.RowDefinitions>

	<ScrollViewer	Grid.Row="0"
					HorizontalScrollMode="Enabled"
					VerticalScrollMode="Disabled" 
					HorizontalScrollBarVisibility="Auto"
					VerticalScrollBarVisibility="Disabled">
			... <!-- your horizontal scrolling content here -->
	</ScrollViewer>
</Grid>

As described above, the important part is the property VerticalScrollBarVisibility="Disabled" which disables the vertical content-expanding completely.

Hope this helps someone. If you have any questions or corrections, please don't hesitate to contact me or write a comment.


comments powered by Disqus