ColumnDefinition.Width of Grid in Viewbox being set to Auto? - wpf-controls

For a scoreboard app I'm building the client wants a particular look for the the team name and score:
Since I need to use these in various places in the UI, I figured I'd wrap them as a UserControl. Here's XAML for the image shown above (which has been significantly simplified from the actual):
<UserControl x:Class="Scoreboard.TeamNameAndScoreControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Scoreboard"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="100">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Label
Name="TeamName"
BorderBrush="AliceBlue"
BorderThickness="1"
Content="WEST"
FontSize="20"
Padding="0"
Background="Gray"
FontWeight="Bold"
HorizontalContentAlignment="Center"
/>
<Label
Name="Score"
BorderBrush="AliceBlue"
BorderThickness="1"
Content="2"
Grid.Column="1"
Padding="0"
Background="White"
FontSize="20"
FontWeight="Bold"
HorizontalContentAlignment="Center"
/>
</Grid>
</UserControl>
What's important to note, for the purposes of this question, is that the 5-2 proportional sizing of the TeamName and Score labels is critical.
Since some of the various locations within the app's UI that I want to use this control are differently sized, and since I want the control to proportionally respond to window size changes, I figured I'd wrap the Grid in a Viewbox:
<UserControl x:Class="Scoreboard.TeamNameAndScoreControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Scoreboard"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="100">
<Viewbox>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Label
BorderBrush="AliceBlue"
BorderThickness="1"
Content="WEST"
FontSize="20"
Padding="0"
Background="Gray"
FontWeight="Bold"
HorizontalContentAlignment="Center"
/>
<Label
BorderBrush="AliceBlue"
BorderThickness="1"
Content="2"
Grid.Column="1"
Padding="0"
Background="White"
FontSize="20"
FontWeight="Bold"
HorizontalContentAlignment="Center"
/>
</Grid>
</Viewbox>
</UserControl>
The problem is that when wrapped by the Viewbox, the Grid seems to convert the ColumnDefinition.Width values effectively to "Auto", so that the result looks like this:
I've tried every possible combination of the Viewbox.Stretch and Viewbox.StretchDirection properties which of course significantly change the appearance, but do not "fix" the issue with the Grid's column widths.
Changing the HorizontalContentAlignment of the Labels seems to have no effect.
I have tried setting setting the SharedSizeGroup attribute but no joy:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*" SharedSizeGroup="A"/>
<ColumnDefinition Width="2*" SharedSizeGroup="A"/>
</Grid.ColumnDefinitions>
I've tried restructuring to instead just wrap each Label in a Viewbox, but the Viewboxes don't fill the Grid cells, making it look just weird:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Viewbox>
<Label
BorderBrush="AliceBlue"
BorderThickness="1"
Content="WEST"
FontSize="20"
Padding="0"
Background="Gray"
FontWeight="Bold"
HorizontalContentAlignment="Center"
/>
</Viewbox>
<Viewbox Grid.Column="1">
<Label
BorderBrush="AliceBlue"
BorderThickness="1"
Content="2"
Padding="0"
Background="White"
FontSize="20"
FontWeight="Bold"
HorizontalContentAlignment="Center"
/>
</Viewbox>
</Grid>
Please note again that the images and XAML shown here have been significantly simplified for the purposes of this question, and actually include an extensive set of styles to enhance the look of the borders, backgrounds, and fonts of each Label. The point is, the fix will unfortunately not be as simple as setting the background of the Grid (or something like that).
So, any thoughts as to why are my ColumnDefinition.Width values seemingly being changed to Auto and how can I fix it?

I've largely figured it out.
I needed to manually set the Width/Height of the Grid, which forced the Viewbox (which takes its size from its child) to be the same size:
<UserControl x:Class="Scoreboard.TeamNameAndScoreControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Scoreboard"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="100">
<Viewbox>
<Grid Width="100" Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Label
BorderBrush="AliceBlue"
BorderThickness="1"
Content="WEST"
FontSize="20"
Padding="0"
Background="Gray"
FontWeight="Bold"
HorizontalContentAlignment="Center"
/>
<Label
BorderBrush="AliceBlue"
BorderThickness="1"
Content="2"
Grid.Column="1"
Padding="0"
Background="White"
FontSize="20"
FontWeight="Bold"
HorizontalContentAlignment="Center"
/>
</Grid>
</Viewbox>
</UserControl>
Now the Grid is honoring the 5*/2* column widths I'd assigned.
It's now clear (to me) that before I made this change the Grid really had no idea how large to make itself (since when I added the Viewbox the Grid went from having a parent that dictated its size - the UserControl - to a parent that gets its size from its child). So apparently under these circumstances it simply decides to have each cell wrap (take its size from) its children (i.e. "Auto" sizing).

Related

[UWP][VisualState] Custom ListViewItem hover presentation

I would like to add hover actions to a ListViewItem, but it seems that in the ListViewItem.DataTemplate the "PointerOver" state is not triggered.
I was creating a custom ItemContainerStyle but in this style, I can just set specific properties related to the TargetType 'ListViewItem'. In my case, I would like to have a button which is only visible, when the user hover over the item.
I want to use the VisualStateManager, but maybe I havn´t understood the concept behind styles, templates and user interaction with bindings in between.
Are there good references/documentation for this?
Thank you in advance
[UWP][VisualState] Custom ListViewItem hover presentation
For your requirement, the better way is
XamlBehaviors to edit the property witin DataTempate. For the detail please refer the following code.
<ListView x:Name="MyListView">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Name="GridPanel">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="InfoTextBlock" Text="{Binding}" />
<TextBlock
x:Name="FlagTextBlock"
Grid.Column="1"
Text="Hover"
Visibility="Collapsed"
>
<Interactivity:Interaction.Behaviors>
<Interactions:EventTriggerBehavior EventName="PointerEntered" SourceObject="{Binding ElementName=GridPanel}">
<Interactions:ChangePropertyAction
PropertyName="Visibility"
TargetObject="{Binding ElementName=FlagTextBlock}"
Value="Visible"
/>
<Interactions:ChangePropertyAction
PropertyName="Foreground"
TargetObject="{Binding ElementName=InfoTextBlock}"
Value="Red"
/>
</Interactions:EventTriggerBehavior>
<Interactions:EventTriggerBehavior EventName="PointerExited" SourceObject="{Binding ElementName=GridPanel}">
<Interactions:ChangePropertyAction
PropertyName="Visibility"
TargetObject="{Binding ElementName=FlagTextBlock}"
Value="Collapsed"
/>
<Interactions:ChangePropertyAction
PropertyName="Foreground"
TargetObject="{Binding ElementName=InfoTextBlock}"
Value="Black"
/>
</Interactions:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<x:String>Hello Test</x:String>
<x:String>Hello Test</x:String>
<x:String>Hello Test</x:String>
</ListView>

Xamarin Forms - Achieve 2 columns with label / value pairs

Is it possible to achieve the following layout in Xamarin Forms:
A couple of notes:
Ideally I want a value to be able to wrap onto 2 lines - in which case the whole row would become taller (row meaning label 1, value 1, label 2, value 2).
Grid() has known issues with word wrap.
I don't know why you think grid has word wrapping issues. I've used grid in many of my apps exactly for this scenario. Here is the code.
<Grid
ColumnSpacing="10"
RowSpacing="10"
HorizontalOptions="FillAndExpand"
VerticalOptions="Start">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
Text="label 1:"
FontAttributes="Bold"
HorizontalOptions="Start"/>
<Label
Grid.Row="0"
Grid.Column="1"
Text="value 1"/>
<Label
Grid.Row="0"
Grid.Column="3"
Text="label 2:"
FontAttributes="Bold"
HorizontalOptions="Start"/>
<Label
Grid.Row="0"
Grid.Column="4"
Text="value 2 is very very infinitely long and can potentially wrap to many many lines"/>
<Label
Grid.Row="1"
Grid.Column="0"
Text="label 3:"
FontAttributes="Bold"
HorizontalOptions="Start"/>
<Label
Grid.Row="1"
Grid.Column="1"
Text="value 3"/>
<Label
Grid.Row="1"
Grid.Column="3"
Text="label 4:"
FontAttributes="Bold"
HorizontalOptions="Start"/>
<Label
Grid.Row="1"
Grid.Column="4"
Text="value 4 goes here"/>
<Label
Grid.Row="2"
Grid.Column="0"
Text="label 5:"
FontAttributes="Bold"
HorizontalOptions="Start"/>
<Label
Grid.Row="2"
Grid.Column="1"
Text="value 5"/>
<Label
Grid.Row="2"
Grid.Column="3"
Text="label 6:"
FontAttributes="Bold"
HorizontalOptions="Start"/>
<Label
Grid.Row="2"
Grid.Column="4"
Text="value 6 here"/>
</Grid>
And here are screenshots for iOS and Android

WinRT XAML Toolkit TreeView expanded display

I am developing a Windows store app. At a high level, the page has a Grid with two rows. Along with other controls, the ComboBox is placed in the first row.
The second row has a GridView and the red tile is one of the items in the GridView. The ComboBox is used to display hierarchical data as shown here.
ComboBox
I am working on replacing the ComboBox with a TreeView from WinRT XAML Toolkit as shown here.
TreeView
What I like about the Combobox is that when its open, the opened list sits on top of the GridView. For the Treeview, when I open the parent node, the opened list stays within the specified height along with the scrollbar.
I would like the TreeView to act like the ComboBox so that when opened, it extends out and the opened list sits on top of the GridView. Any idea how I can accomplish that?
Thanks for your help.
Set something like this on the TreeView (adjust max dimensions for available space)
VerticalAlignment="Top"
HorizontalAlignment="Left"
MaxHeight="500"
MaxWidth="500"
Canvas.ZIndex="1"
This will make the ScrollViewer and the TreeView change the size depending on the size of expanded tree up to a max size where it will start scrolling. The ZIndex will make it render on top of items with lower or default ZIndex value at the same level in the visual tree.
You could also put it in a Popup when your root node expands and back out of the Popup when the Popup closes or when the node collapses.
*EDIT
Based on your code - I can see you have a bit of a mess of a lot of nested panels, but with a simple hack you can make it work even with your layout. There are three things to do:
Make the TreeView top-aligned as I mentioned earlier.
The height of the panel the TreeView is inside of is a bit limited (to 20% of page height) by the size of the Grid row it's in. You can add a bit more space by setting a large enough negative bottom Margin value for the TreeView.
Since the TreeView is in the first row of the grid - the second row naturally overlays it when the TreeView extends into the negative margin. You can fix that by setting Canvas.ZIndex="1" on the StackPanel that is the root of your first row or reordering your row elements to reverse the ZIndex.
Here's the updated code:
<Page
x:Class="TestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp"
xmlns:custom="using:TestApp.Custom"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:WinRTXamlToolkit.Controls"
xmlns:data="using:WinRTXamlToolkit.Controls.Data"
mc:Ignorable="d">
<Page.Resources>
<Style x:Key="HorizontalScrollViewerStyle" TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="VerticalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Enabled" />
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled" />
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="2*"></RowDefinition>
<RowDefinition Height="7*"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="0,10,0,0"
Canvas.ZIndex="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" HorizontalAlignment="Left" Margin="50,0,0,0">
<StackPanel>
<TextBlock Text="Version 1.0.0.0"/>
<!--<ProgressBar IsIndeterminate="True" Visibility="{Binding ShowProgressBar, Converter={StaticResource BooleanToVisibility}}" Height="20"/>-->
</StackPanel>
<StackPanel Orientation="Horizontal">
<Image Source="/Assets/SmallLogo.scale-100.png" Width="130" Height="60" Stretch="Uniform"/>
<TextBlock Text="Testing TreeView" FontSize="20" FontWeight="Light" VerticalAlignment="Center" Margin="10"/>
</StackPanel>
</StackPanel>
<StackPanel Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*"/>
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal">
<TextBlock Text="Test ID: 1234" Margin="0,0,5,0" FontWeight="SemiBold" VerticalAlignment="Center"/>
</StackPanel>
</Grid>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBlock Text ="Test Data 123"/>
<TextBlock Text ="More Test Data 123"/>
</StackPanel>
<!--<ComboBox Grid.Row="2"
ItemsSource="{Binding Locations}"
SelectedItem="{Binding SelectedLocation, Mode=TwoWay}"
Width="400" Margin="0,5,0,0" />-->
<controls:TreeView Grid.Row="2" ItemsSource="{Binding TLocations}"
VerticalAlignment="Top"
Width="400" Margin="0,5,0,-1000" MaxHeight="400">
<controls:TreeView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}"/>
<data:DataTemplateExtensions.Hierarchy>
<data:HierarchicalDataTemplate ItemsSource="{Binding Items}" />
</data:DataTemplateExtensions.Hierarchy>
</DataTemplate>
</controls:TreeView.ItemTemplate>
</controls:TreeView>
</Grid>
</StackPanel>
</Grid>
</StackPanel>
<Grid Grid.Row="1" Margin="0,10,0,0">
<!--<Grid.Background>
<ImageBrush ImageSource="/Assets/Background.png" />
</Grid.Background>-->
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
<StackPanel Orientation="Horizontal" >
<StackPanel Margin="50,0,0,0">
<TextBlock Text="Overview" Margin="0,20,0,0" />
<Grid Width="450" Height="450" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="5*" />
<RowDefinition Height="2*" />
<RowDefinition Height="3*" />
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="Assets/StoreLogo.scale-100.png" Stretch="UniformToFill"/>
<StackPanel Grid.Row="1" Background="Azure">
</StackPanel>
<StackPanel Grid.Row="2" Background="Orange">
</StackPanel>
</Grid>
</StackPanel>
<StackPanel Margin="50,20,0,0">
<TextBlock Text="Test Content" Margin="2,0,0,0"/>
<custom:CustomGridView ItemsSource="{Binding Items}" SelectionMode="None">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Horizontal" ItemHeight="150" ItemWidth="175" MaximumRowsOrColumns="3" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<Grid Background="{Binding BackgroundColor}">
<Grid.RowDefinitions>
<RowDefinition Height="{Binding TitleHeight}"/>
<RowDefinition Height="{Binding ImageHeight}" />
<RowDefinition Height="{Binding ContentHeight}" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" VerticalAlignment="Top">
<TextBlock Text="{Binding Title}" HorizontalAlignment="Left" Padding="5,0,0,0"></TextBlock>
</StackPanel>
<StackPanel Grid.Row="1">
<Image Source="{Binding ImageSource}" Stretch="None" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="2" VerticalAlignment="Bottom" Background="{Binding ContentBackgroundColor}">
<TextBlock Text="{Binding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="5"></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</custom:CustomGridView>
</StackPanel>
<!--<userControls:EarnBenefits x:Name="earnBenefits"/>-->
</StackPanel>
</ScrollViewer>
</Grid>
</Grid>
</Page>
Here's a screenshot:
I've also noticed you are targeting Windows 8.1 at least with your test app, but you are using an old Windows 8.0 version (1.6.1.3) of the toolkit. You can get the latest version (1.8.1 as of 2015-02-01) here: http://www.nuget.org/packages/winrtxamltoolkit.windows

XML grid won't expand

I have a parent grid ("Output") hosting 2 smaller grids.
The smaller grids MainDisplay (which basically shows an image in a ViewBox that I want to take all of the horizontal space except for 300 in the other of the 2 sub grids) and Input (a fixed width of 300, which actually works as expected).
My problems are:
1) The parent grid does not consume all the horizontal space. I want the extra space to go to the grid with the ViewBox.
I have sprinkled 'HorizontalAlignment="Stretch"' and 'Width="*"' all over, but it won't take up all the space on the screen!
2) I have code behind to grab the width/height of the image. Unless I explicitly set the height, width the code behind tries to grab the height and width and crashes ... but if I set the width/height explicitly I'm afraid it's not going to grab the available space.
Here is the code:
<Grid x:Name="Output" Background="#1D1D1D" Margin="0,2,0,-2" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
<Grid x:Name="MainDisplay" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Viewbox Width="Auto" Height="Auto" MinWidth="400" MinHeight="400" x:Name="Scenario4ImageContainer" Stretch="Uniform">
<Image x:Name="Scenario4Image" PointerPressed="Scenario4Image_PointerPressed" HorizontalAlignment="Stretch" />
</Viewbox>
</Grid>
<Grid Width="300" x:Name="Input" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock Style="{StaticResource BasicTextStyle}" TextWrapping="Wrap"
Text="Tools" />
<Grid Margin="0,10,0,0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="230" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" Background="DarkSlateGray"
Content="Draw Mandelbrot set" Click="DrawMandelbrotSet_Click" />
<TextBlock x:Name="Scenario4DrawMandelbrotDescription" Grid.Row="0" Grid.Column="1"
Style="{StaticResource BasicTextStyle}" TextWrapping="Wrap" VerticalAlignment="Center"
Text="Text." />
<Button x:Name="Scenario4SetSourceButton" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch"
Content="Load image using SetSource" Click="LoadImageUsingSetSource_Click" />
<TextBlock x:Name="Scenario4SetSourceDescription" Grid.Row="1" Grid.Column="1"
Style="{StaticResource BasicTextStyle}" TextWrapping="Wrap" VerticalAlignment="Center"
Text="Text." />
<Button x:Name="Scenario4LoadImageButton" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Stretch"
Content="Load image using PixelBuffer" Click="LoadImageUsingPixelBuffer_Click" />
<TextBlock x:Name="Scenario4LoadImageDescription" Grid.Row="2" Grid.Column="1"
Style="{StaticResource BasicTextStyle}" TextWrapping="Wrap" VerticalAlignment="Center"
Text="Text." />
</Grid>
</StackPanel>
</Grid>
I'm not 100% sure on this, but try "*" instead of "Auto" in your first column definition:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>

How can I add controls below the default xaml in a Basic Page?

With the VisualStateManager code stripped out for simplicity, the XAML for a Basic Page in a Windows 8 app looks like this:
<!-- Back button and page title -->
<Grid> //row 0 by default
<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="Account Basic Info" Style="{StaticResource PageHeaderTextStyle}"/>
</Grid>
// VisualStateManager extravaganza elided
So the way I read it is that I've got a grid within a grid, and the inner grid is in row 0 of the first grid; the inner grid adds two columns to that first row that it's in and then places a button (in column 0 by default) and a textblock in column 1.
I want to add more controls to the page, but all my attempts/experiments to do so have failed so far (adding rows to the outer grid, then adding rows to the inner grid). To add yet another inner grid (inside the first inner grid) seems a little ridiculous. What is the standard way to pull this off (or "a" way, anyway)?
As you point out, you could add another grid (or StackPanel) after the row zero grid:
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton2" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
<TextBlock x:Name="pageTitle2" Grid.Column="1" Text="{StaticResource AppName}" Style="{StaticResource PageHeaderTextStyle}"/>
</Grid>
Another way to do it is to define more rows in the first grid:
<Grid.RowDefinitions>
<!-- notice there are 4 rows now -->
<RowDefinition Height="140"/>
<RowDefinition Height="140"/>
<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}"/>
</Grid>
<!-- My controls are placed in explict rows using Grid.Row -->
<Button x:Name="backButton2" Grid.Row="1" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
<TextBlock x:Name="pageTitle2" Grid.Row="2" Text="{StaticResource AppName}" Style="{StaticResource PageHeaderTextStyle}"/>
<Button x:Name="backButton3" Grid.Row="3" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>

Resources