locked
ScrollViewer Properties

    Question

  • I have a very simple Windows Store app I'm working on which contains three horizontal grids. Since I am using the blank template, it does not scroll because I am not using any controls that come with the other templates. I added a scrollviewer. I want it to be able to scroll horizontally or vertically depending on the view state. This is what it does with the attached template. It has no visible scrollbar horizontally. Using the mouse wheel makes it scroll vertically and that actually works pretty well. I can pan horizontally with touch but when I get to the end, it doesn't stay but bounces back. I copied the template but I have no idea what to change. I cannot find anything online that is current with Windows 8.1. Is there code behind I am missing? I have read everything I could find about it but I really just don't understand it. Sorry for the long code blocks but I thought you should see everything I am to tell me where I'm going wrong. I appreciate any help.

    Here is partial code from the Main Page Xaml that contains the grids:

    <Grid x:Name="outerGrid" HorizontalAlignment="Left" Height="683" VerticalAlignment="Top" Width="1360" Grid.ColumnSpan="2" Margin="9,77,-3,-620">
                        <Grid x:Name="mainGrid" Margin="0,198,925,112" Background="#FF1D414A">
                            <Button x:Name="photoButton" Content="My Fav Photo" HorizontalAlignment="Left" Margin="149,307,0,0" VerticalAlignment="Top" Click="getPhotoButton_Click" Height="57" RenderTransformOrigin="0.5,0.5"/>
                            <Image x:Name="myImage" HorizontalAlignment="Center" Height="183" Margin="92,104,71,0" VerticalAlignment="Top" Width="267" Source="Assets/kg.jpg"/>
                        </Grid>
                        <Grid x:Name="middleGrid" Margin="435,72,276,40" Background="#FF1D414A">
                            <StackPanel x:Name="rowOne" HorizontalAlignment="Left" Height="154" VerticalAlignment="Top" Width="560" RenderTransformOrigin="0.57,0.64" Margin="25,120,0,0" Orientation="Horizontal">
                                <Image x:Name="imageOne" Width="163"  Source="Assets/triangle.png" Margin="10,0,0,0"/>
                                <Image x:Name="imageTwo" Width="163" Source="Assets/Logo.png" Margin="20,0,0,0"/>
                                <Image x:Name="imageThree" Width="163" Source="Assets/Logo.png"/>
                            </StackPanel>
                            <StackPanel x:Name="rowTwo" HorizontalAlignment="Left" Height="154" VerticalAlignment="Top" Width="560" Margin="25,327,0,0" Orientation="Horizontal">
                                <Image x:Name="imageFour" Width="163" Source="Assets/Logo.png" Margin="20,0,0,0"/>
                                <Image x:Name="imageFive" Width="163" Source="Assets/Logo.png"/>
                                <Image x:Name="image6" Width="163" Source="Assets/Logo.png"/>
                            </StackPanel>
                            <StackPanel x:Name="textPanelOne" HorizontalAlignment="Left" Height="72" VerticalAlignment="Top" Width="567" Margin="42,87,0,0" Orientation="Horizontal">
                                <TextBlock x:Name="itemOne" TextWrapping="Wrap" Text="Item One" Width="173" Margin="0,0,0,48" Foreground="White" SelectionHighlightColor="#FF1D414A"/>
                                <TextBlock x:Name="itemTwo" TextWrapping="Wrap" Text="ItemTwo" Width="201" Margin="0,0,0,48"/>
                                <TextBlock x:Name="itemThree" TextWrapping="Wrap" Text="ItemThree" Width="180" Margin="0,0,0,48"/>
                            </StackPanel>
                        </Grid>
                        <Grid x:Name="lastGrid" Margin="1084,198,-92,112" Background="#FF1D414A">
                            <Image x:Name="backgroundImage" HorizontalAlignment="Center" Height="188" Margin="10,260,-6,-75" VerticalAlignment="Center" Width="272" Source="Assets/nikon.png"/>
                        </Grid>
                    </Grid>
                </Grid>
    And this is the template code. I have changed a couple things but it doesn't make any difference except making the vertical scrollbar invisible.

    <Style x:Key="ScrollViewerStyle1" TargetType="ScrollViewer">
    			<Setter Property="HorizontalScrollMode" Value="Enabled"/>
    			<Setter Property="VerticalScrollMode" Value="Enabled"/>
    			<Setter Property="IsHorizontalRailEnabled" Value="True"/>
    			<Setter Property="IsVerticalRailEnabled" Value="True"/>
    			<Setter Property="IsTabStop" Value="True"/>
    			<Setter Property="ZoomMode" Value="Enabled"/>
    			<Setter Property="HorizontalContentAlignment" Value="Left"/>
    			<Setter Property="VerticalContentAlignment" Value="Top"/>
    			<Setter Property="VerticalScrollBarVisibility" Value="Visible"/>
    			<Setter Property="Padding" Value="20"/>
    			<Setter Property="BorderThickness" Value="2"/>
    			<Setter Property="BorderBrush" Value="Red"/>
    			<Setter Property="Background" Value="Aqua"/>
    			<Setter Property="Template">
    				<Setter.Value>
    					<ControlTemplate TargetType="ScrollViewer">
    						<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="2" Background="Black" Width="2000">
    							<VisualStateManager.VisualStateGroups>
    								<VisualStateGroup x:Name="ScrollingIndicatorStates">
    									<VisualStateGroup.Transitions>
    										<VisualTransition From="MouseIndicator" To="NoIndicator">
    											<Storyboard>
    												<FadeOutThemeAnimation BeginTime="0:0:3" TargetName="ScrollBarSeparator"/>
    												<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IndicatorMode" Storyboard.TargetName="VerticalScrollBar">
    													<DiscreteObjectKeyFrame KeyTime="0:0:3">
    														<DiscreteObjectKeyFrame.Value>
    															<ScrollingIndicatorMode>None</ScrollingIndicatorMode>
    														</DiscreteObjectKeyFrame.Value>
    													</DiscreteObjectKeyFrame>
    												</ObjectAnimationUsingKeyFrames>
    												<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IndicatorMode" Storyboard.TargetName="HorizontalScrollBar">
    													<DiscreteObjectKeyFrame KeyTime="0:0:3">
    														<DiscreteObjectKeyFrame.Value>
    															<ScrollingIndicatorMode>None</ScrollingIndicatorMode>
    														</DiscreteObjectKeyFrame.Value>
    													</DiscreteObjectKeyFrame>
    												</ObjectAnimationUsingKeyFrames>
    											</Storyboard>
    										</VisualTransition>
    										<VisualTransition From="TouchIndicator" To="NoIndicator">
    											<Storyboard>
    												<FadeOutThemeAnimation TargetName="ScrollBarSeparator"/>
    												<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IndicatorMode" Storyboard.TargetName="VerticalScrollBar">
    													<DiscreteObjectKeyFrame KeyTime="0:0:0.5">
    														<DiscreteObjectKeyFrame.Value>
    															<ScrollingIndicatorMode>None</ScrollingIndicatorMode>
    														</DiscreteObjectKeyFrame.Value>
    													</DiscreteObjectKeyFrame>
    												</ObjectAnimationUsingKeyFrames>
    												<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IndicatorMode" Storyboard.TargetName="HorizontalScrollBar">
    													<DiscreteObjectKeyFrame KeyTime="0:0:0.5">
    														<DiscreteObjectKeyFrame.Value>
    															<ScrollingIndicatorMode>None</ScrollingIndicatorMode>
    														</DiscreteObjectKeyFrame.Value>
    													</DiscreteObjectKeyFrame>
    												</ObjectAnimationUsingKeyFrames>
    											</Storyboard>
    										</VisualTransition>
    									</VisualStateGroup.Transitions>
    									<VisualState x:Name="NoIndicator">
    										<Storyboard>
    											<FadeOutThemeAnimation TargetName="ScrollBarSeparator"/>
    										</Storyboard>
    									</VisualState>
    									<VisualState x:Name="TouchIndicator">
    										<Storyboard>
    											<FadeOutThemeAnimation TargetName="ScrollBarSeparator"/>
    											<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="IndicatorMode" Storyboard.TargetName="VerticalScrollBar">
    												<DiscreteObjectKeyFrame KeyTime="0">
    													<DiscreteObjectKeyFrame.Value>
    														<ScrollingIndicatorMode>TouchIndicator</ScrollingIndicatorMode>
    													</DiscreteObjectKeyFrame.Value>
    												</DiscreteObjectKeyFrame>
    											</ObjectAnimationUsingKeyFrames>
    											<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="IndicatorMode" Storyboard.TargetName="HorizontalScrollBar">
    												<DiscreteObjectKeyFrame KeyTime="0">
    													<DiscreteObjectKeyFrame.Value>
    														<ScrollingIndicatorMode>TouchIndicator</ScrollingIndicatorMode>
    													</DiscreteObjectKeyFrame.Value>
    												</DiscreteObjectKeyFrame>
    											</ObjectAnimationUsingKeyFrames>
    										</Storyboard>
    									</VisualState>
    									<VisualState x:Name="MouseIndicator">
    										<Storyboard>
    											<FadeInThemeAnimation TargetName="ScrollBarSeparator"/>
    											<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="IndicatorMode" Storyboard.TargetName="VerticalScrollBar">
    												<DiscreteObjectKeyFrame KeyTime="0">
    													<DiscreteObjectKeyFrame.Value>
    														<ScrollingIndicatorMode>MouseIndicator</ScrollingIndicatorMode>
    													</DiscreteObjectKeyFrame.Value>
    												</DiscreteObjectKeyFrame>
    											</ObjectAnimationUsingKeyFrames>
    											<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="IndicatorMode" Storyboard.TargetName="HorizontalScrollBar">
    												<DiscreteObjectKeyFrame KeyTime="0">
    													<DiscreteObjectKeyFrame.Value>
    														<ScrollingIndicatorMode>MouseIndicator</ScrollingIndicatorMode>
    													</DiscreteObjectKeyFrame.Value>
    												</DiscreteObjectKeyFrame>
    											</ObjectAnimationUsingKeyFrames>
    										</Storyboard>
    									</VisualState>
    								</VisualStateGroup>
    							</VisualStateManager.VisualStateGroups>
    							<Grid Background="{TemplateBinding Background}" Margin="-324,0,316,0">
    								<Grid.ColumnDefinitions>
    									<ColumnDefinition Width="*"/>
    									<ColumnDefinition Width="Auto"/>
    								</Grid.ColumnDefinitions>
    								<Grid.RowDefinitions>
    									<RowDefinition Height="*"/>
    									<RowDefinition Height="Auto"/>
    								</Grid.RowDefinitions>
    								<ScrollContentPresenter x:Name="ScrollContentPresenter" Grid.ColumnSpan="2" 
                                                            ContentTemplate="{TemplateBinding ContentTemplate}" 
                                                            Margin="{TemplateBinding Padding}" Grid.RowSpan="2"/>
    								<ScrollBar x:Name="VerticalScrollBar" Grid.Column="1" HorizontalAlignment="Right"
                                               IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" 
                                               Orientation="Vertical" Value="{TemplateBinding VerticalOffset}" 
                                               ViewportSize="{TemplateBinding ViewportHeight}" Visibility="Collapsed"/>
    								<ScrollBar x:Name="HorizontalScrollBar" IsTabStop="True" 
                                               Maximum="{TemplateBinding ScrollableWidth}"
                                               Orientation="Horizontal" Grid.Row="1" 
                                               Visibility="{Binding Visibility, RelativeSource={RelativeSource Mode=TemplatedParent}}"
                                               Value="{TemplateBinding HorizontalOffset}" 
                                               ViewportSize="{TemplateBinding ViewportWidth}" Height="20" VerticalAlignment="Top"/>
    								<Border x:Name="ScrollBarSeparator" BorderBrush="{ThemeResource ScrollBarTrackBorderThemeBrush}" 
                                            BorderThickness="0,0,1,1" Background="{ThemeResource ScrollBarTrackBackgroundThemeBrush}" 
                                            Grid.Column="3" Grid.Row="1"/>
    							</Grid>
    						</Border>
    					</ControlTemplate>
    				</Setter.Value>
    			</Setter>
    		</Style>

    Friday, May 30, 2014 10:08 PM

Answers

  • You shouldn't have to do anything special for touch. Your code snippet works for me with touch exactly as I expect it to. I can swipe left or right to scroll and it persists where I lift my finger (after a small bit of inertia).

    Monday, June 02, 2014 11:02 PM
    Owner

All replies

  • Apps control the ScrollViewer's scrollbars via the HorizontalScrollMode, VerticalScrollMode, HorizontalScrollBarVisibilty, and VerticalScrollBarVisibility properties. You shouldn't need to retemplate the ScrollViewer for this.

    You don't include the ScrollViewer in your Xaml code so it's not clear what you're actually doing with it. Make sure you have the appropriate visibilities set and that the contents are large enough to require scrolling.

    Saturday, May 31, 2014 3:16 AM
    Owner
  • Apps control the ScrollViewer's scrollbars via the HorizontalScrollMode, VerticalScrollMode, HorizontalScrollBarVisibilty, and VerticalScrollBarVisibility properties. You shouldn't need to retemplate the ScrollViewer for this.

    You don't include the ScrollViewer in your Xaml code so it's not clear what you're actually doing with it. Make sure you have the appropriate visibilities set and that the contents are large enough to require scrolling.

    Thanks for the quick answer. That's what I thought but it just wasn't working which is why I was trying to change the template.  I did make the width longer than the screen width. I found a very simple example on MSDN and using that set up a test which works fine. This makes a little box that does scroll.

     <ScrollViewer ZoomMode="Enabled" MaxZoomFactor="10" 
            	HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Visible"
            	Height="200" Width="200" Margin="511,160,655,268" Grid.Row="1">
               <StackPanel Orientation="Horizontal" Width="600" Background="Crimson">
                    <Grid x:Name="wideGrid" Width="600"></Grid>
                </StackPanel>
            </ScrollViewer>

    Of course, I have a lot more content. I am assuming that the scrollveiwer tags are outside the content you want to scroll. So I went back and worked on it. I now have a scrollbar that scrolls with a mouse but touch is not working correctly. You can pan to the right with touch but when you remove your finger it snaps back to the left margin. I still have to deal with different view states too since it won't work in snapped mode either. However, the goal right now is to get it working in full landscape mode. Thanks again. You got me going in the right direction. I think I have to modify something in the template or add something to the Xaml to make it work correctly for touch?

    Saturday, May 31, 2014 3:43 PM
  • You shouldn't have to do anything special for touch. Your code snippet works for me with touch exactly as I expect it to. I can swipe left or right to scroll and it persists where I lift my finger (after a small bit of inertia).

    Monday, June 02, 2014 11:02 PM
    Owner