locked
Stacking controls wider than a page

    Question

  • I would like to lay down controls, which together, are wider than the default width of a Windows Store app page, and hence exceeds the boundaries of the page. I use a ScrollViewer control, as follows:

        <ScrollViewer HorizontalScrollMode="Auto"  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"  >       
    </Grid>
                <Canvas HorizontalAlignment="Left" Height="100" Margin="326,161,0,0" Grid.Row="1" VerticalAlignment="Top" Width="810">
                    <TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="772" Canvas.Left="10" Canvas.Top="29"/>
                </Canvas>
            </Grid>
        </ScrollViewer>

    If the canvas (containing the text box) within the ScrollViewer is before the right edge of the app page in design view, the control works normally. If I move the canvas to the right, so that the text box within it is partially cut off from view by the edge of the page, I'm not able to scroll over and see the cut off section of the text box control, when the app is running. Again, is there a way that I can lay down controls, which together are wider than the width of an app page, so that when the app is running, the user is able to scroll and see all of the controls? Thank you.

    • Edited by PDoug Saturday, June 28, 2014 3:03 PM
    Saturday, June 28, 2014 2:56 PM

Answers

  • Hi PDoug,

    of course it is possible. There are several ways. The standard-project-templates already contain controls that are wider than the page. In your case I would just use a horizontal StackPanel inside of the ScrollViewer like this:

          <ScrollViewer HorizontalScrollMode="Auto"  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"  >
                <StackPanel Orientation="Horizontal">
                    <TextBox TextWrapping="Wrap" Text="TextBox1"  Width="772" />
                    <TextBox TextWrapping="Wrap" Text="TextBox2"  Width="772" />
                    <TextBox TextWrapping="Wrap" Text="TextBox3"  Width="772" />
                    <TextBox TextWrapping="Wrap" Text="TextBox4"  Width="772" />
                </StackPanel>
            </ScrollViewer>


    Thomas Claudius Huber

    "If you can't make your app run faster, make it at least look & feel extremly fast"

    My latest app: The "Womanizer" :-)
    twitter: @thomasclaudiush
    homepage: www.thomasclaudiushuber.com
    author of: ultimate Windows Store Apps handbook | ultimate WPF handbook | ultimate Silverlight handbook

    • Marked as answer by PDoug Monday, June 30, 2014 11:18 AM
    Saturday, June 28, 2014 7:53 PM
  • Thomas,

    Thanks for your suggestion. Based on the example you provided, and some tests, I modified my code as follows:

      <ScrollViewer HorizontalScrollMode="Auto"  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"  >       
    </Grid>
                <Canvas>
                    <Button Height="90" Width="180" Canvas.Top="104" Content="Push" Canvas.Left="61"></Button>
                </Canvas>
    <StackPanel Height="400" Margin="260,103,-60,265" Orientation="Horizontal" VerticalAlignment="Top">
                    <TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="772" Canvas.Left="10" Canvas.Top="29"/>
    </StackPanel>
            </Grid>
        </ScrollViewer>

    The takeaway from the above, is that if you want a set of controls to be able to be placed beyond the edge of an app page, place them within a StackPanel control (with a horizontal orientation), which is in turn inserted into a grid within a ScrollViewer control. The controls you place in the StackPanel control can be placed on a Canvas control, which is in turn placed directly into the StackPanel control. This allows your controls to be more freely organized on an app page, while also being scrollable.

    Once again, thanks for your suggestion.

    • Marked as answer by PDoug Monday, June 30, 2014 11:18 AM
    • Edited by PDoug Monday, June 30, 2014 11:20 AM
    Monday, June 30, 2014 11:18 AM
  • Another important thing to note, is that if you are using a Basic app page, with a title and back arrow at the top left of the page, you should enclose the contents of your page with a grid, contained within a ScrollViewer control, as shown in the following example:

        <Page.Resources>
    
            <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
            <x:String x:Key="AppName">Addresses</x:String>
        </Page.Resources>
        <ScrollViewer HorizontalScrollMode="Auto"  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"  >
            <Grid>
    
                <Grid Style="{StaticResource LayoutRootStyle}">
    
    
                    <Grid.RowDefinitions>
                        <RowDefinition Height="140"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
    
                    <!-- Back button and page title -->
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
                        <TextBlock x:Name="pageTitle" Grid.Column="1" Text="{StaticResource AppName}" Style="{StaticResource PageHeaderTextStyle}" FontSize="48"/>
                    </Grid>
    
                    <StackPanel Margin="203,310,-83,0" Orientation="Horizontal" VerticalAlignment="Top" Grid.Row="1">
                        <TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox                                             0                9             0       888                             9" VerticalAlignment="Top" Width="772" Canvas.Left="10" Canvas.Top="29"/>
                        <TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox                                             0                9             0       888                             9" VerticalAlignment="Top" Width="772" Canvas.Left="10" Canvas.Top="29"/>
                        <TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox                                             0                9             0       888                             9" VerticalAlignment="Top" Width="772" Canvas.Left="10" Canvas.Top="29"/>
                    </StackPanel>
    
                </Grid>
            </Grid>
        </ScrollViewer>

    You can then place your StackPanel control, directly within the second level grid control. This will allow the controls within your StackPanel control, to scroll beyond the edge of your app page.

    • Edited by PDoug Monday, June 30, 2014 12:22 PM
    • Marked as answer by PDoug Monday, June 30, 2014 12:22 PM
    Monday, June 30, 2014 12:18 PM

All replies

  • Hi PDoug,

    of course it is possible. There are several ways. The standard-project-templates already contain controls that are wider than the page. In your case I would just use a horizontal StackPanel inside of the ScrollViewer like this:

          <ScrollViewer HorizontalScrollMode="Auto"  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"  >
                <StackPanel Orientation="Horizontal">
                    <TextBox TextWrapping="Wrap" Text="TextBox1"  Width="772" />
                    <TextBox TextWrapping="Wrap" Text="TextBox2"  Width="772" />
                    <TextBox TextWrapping="Wrap" Text="TextBox3"  Width="772" />
                    <TextBox TextWrapping="Wrap" Text="TextBox4"  Width="772" />
                </StackPanel>
            </ScrollViewer>


    Thomas Claudius Huber

    "If you can't make your app run faster, make it at least look & feel extremly fast"

    My latest app: The "Womanizer" :-)
    twitter: @thomasclaudiush
    homepage: www.thomasclaudiushuber.com
    author of: ultimate Windows Store Apps handbook | ultimate WPF handbook | ultimate Silverlight handbook

    • Marked as answer by PDoug Monday, June 30, 2014 11:18 AM
    Saturday, June 28, 2014 7:53 PM
  • Thomas,

    Thanks for your suggestion. Based on the example you provided, and some tests, I modified my code as follows:

      <ScrollViewer HorizontalScrollMode="Auto"  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"  >       
    </Grid>
                <Canvas>
                    <Button Height="90" Width="180" Canvas.Top="104" Content="Push" Canvas.Left="61"></Button>
                </Canvas>
    <StackPanel Height="400" Margin="260,103,-60,265" Orientation="Horizontal" VerticalAlignment="Top">
                    <TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="772" Canvas.Left="10" Canvas.Top="29"/>
    </StackPanel>
            </Grid>
        </ScrollViewer>

    The takeaway from the above, is that if you want a set of controls to be able to be placed beyond the edge of an app page, place them within a StackPanel control (with a horizontal orientation), which is in turn inserted into a grid within a ScrollViewer control. The controls you place in the StackPanel control can be placed on a Canvas control, which is in turn placed directly into the StackPanel control. This allows your controls to be more freely organized on an app page, while also being scrollable.

    Once again, thanks for your suggestion.

    • Marked as answer by PDoug Monday, June 30, 2014 11:18 AM
    • Edited by PDoug Monday, June 30, 2014 11:20 AM
    Monday, June 30, 2014 11:18 AM
  • Another important thing to note, is that if you are using a Basic app page, with a title and back arrow at the top left of the page, you should enclose the contents of your page with a grid, contained within a ScrollViewer control, as shown in the following example:

        <Page.Resources>
    
            <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
            <x:String x:Key="AppName">Addresses</x:String>
        </Page.Resources>
        <ScrollViewer HorizontalScrollMode="Auto"  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"  >
            <Grid>
    
                <Grid Style="{StaticResource LayoutRootStyle}">
    
    
                    <Grid.RowDefinitions>
                        <RowDefinition Height="140"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
    
                    <!-- Back button and page title -->
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
                        <TextBlock x:Name="pageTitle" Grid.Column="1" Text="{StaticResource AppName}" Style="{StaticResource PageHeaderTextStyle}" FontSize="48"/>
                    </Grid>
    
                    <StackPanel Margin="203,310,-83,0" Orientation="Horizontal" VerticalAlignment="Top" Grid.Row="1">
                        <TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox                                             0                9             0       888                             9" VerticalAlignment="Top" Width="772" Canvas.Left="10" Canvas.Top="29"/>
                        <TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox                                             0                9             0       888                             9" VerticalAlignment="Top" Width="772" Canvas.Left="10" Canvas.Top="29"/>
                        <TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox                                             0                9             0       888                             9" VerticalAlignment="Top" Width="772" Canvas.Left="10" Canvas.Top="29"/>
                    </StackPanel>
    
                </Grid>
            </Grid>
        </ScrollViewer>

    You can then place your StackPanel control, directly within the second level grid control. This will allow the controls within your StackPanel control, to scroll beyond the edge of your app page.

    • Edited by PDoug Monday, June 30, 2014 12:22 PM
    • Marked as answer by PDoug Monday, June 30, 2014 12:22 PM
    Monday, June 30, 2014 12:18 PM