Search code examples
xamllayoutwindows-phone-8.1stackpanel

How to layout a stack of textblocks using stackpanels and grid?


I have a basic UI where there are 6 textblocks, 3 for the values and 3 for the related headers. What I had set out originally was positioning the textblocks using the grid and column positions. This looked fine except for the value textblocks were positioned too close to their header teckblocks.

So to try an alternative solution, in my below code I wrapped each set of textblocks in a stackpanel and supplied a margin for the header textblock. But when testing all six controls appear bunched up together in the top right corner of the screen.

Question: Does anyone know how to position a set of textblocks, stacked and with a space between the first and second block in each set?

During debug I tried playing around with the margin size on each stackpanel which didn't do anything to fix the layout.

Xaml markup of the UI:

<Grid x:Name="LayoutRoot" Background="#FF236A93">

    <Grid.ChildrenTransitions>
        <TransitionCollection>
            <EntranceThemeTransition />
        </TransitionCollection>
    </Grid.ChildrenTransitions>

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



    <!--  ContentPanel contains details text. Place additional content here  -->
    <Grid x:Name="ContentPanel"
          Grid.Row="1"
          Height="600"
          Margin="5,0,5,0"
          Visibility="Visible">
        <Grid.RowDefinitions>
            <RowDefinition Height="1.6*" />
            <RowDefinition Height="1.6*" />
            <RowDefinition Height="1.6*" />
            <RowDefinition Height="2*" />
            <RowDefinition Height="2*" />
            <RowDefinition Height="1.3*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width=".5*" />
            <ColumnDefinition Width="5*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>


        <StackPanel Orientation="Horizontal">
            <TextBlock Grid.Row="0"
                   Grid.Column="1"
                   Margin="0,0,5,0"
                   Width="270"
                   Height="72"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Top"
                   FontSize="24"
                   Foreground="Gray"
                   Text="Hourly Tariff:" />


            <TextBlock Grid.Row="0"
                   Grid.Column="1"
                   Width="270"
                   Height="72"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Bottom"
                   FontSize="24"
                   Foreground="White"
                   Text="{Binding SelectedZone.TariffPH}" />
        </StackPanel>


        <StackPanel Orientation="Horizontal">
            <TextBlock Grid.Row="1"
                   Grid.Column="1"
                   Width="270"
                   Height="72"
                   Margin="0,0,5,0"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Top"
                   FontSize="24"
                   Foreground="Gray"
                   Text="Hours Open:" />

            <TextBlock Grid.Row="1"
                   Grid.Column="1"
                   Width="270"
                   Height="72"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Bottom"
                   FontSize="24"
                   Foreground="White"
                   Text="{Binding SelectedZone.HoursOpen}" />
        </StackPanel>



        <StackPanel Orientation="Horizontal">
            <TextBlock Grid.Row="2"
                   Grid.Column="1"
                   Width="270"
                   Height="72"
                   Margin="0,0,5,0"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Top"
                   FontSize="24"
                   Foreground="Gray"
                   Text="Days Open:" />

            <TextBlock Grid.Row="2"
                   Grid.Column="1"
                   Width="270"
                   Height="72"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Bottom"
                   FontSize="24"
                   Foreground="White"
                   Text="{Binding SelectedZone.DaysOpen}" />
        </StackPanel>



        <StackPanel Orientation="Horizontal">
            <TextBlock Grid.Row="3"
                   Grid.Column="1"
                   Width="270"
                   Height="72"
                   Margin="0,0,5,0"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Top"
                   FontSize="24"
                   Foreground="Gray"
                   Text="Parking Restrictions:" />


            <TextBlock Grid.Row="3"
                   Grid.Column="1"
                   Width="270"
                   Height="72"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Bottom"
                   FontSize="24"
                   Foreground="White"
                   Text="{Binding SelectedZone.Restrictions}" />
        </StackPanel>








    </Grid>
</Grid>

Proposed layout of UI:

Proposed layout


Solution

  • If it were me, I'd just turn all that noise into something more like this for easier maintenance/readability and less objects in the DOM;

     <!--  ContentPanel contains details text. Place additional content here  -->
        <StackPanel x:Name="ContentPanel"
              Grid.Row="1" Margin="5,0">
              <StackPanel.Resources>
                <Style TargetType="TextBlock">
                  <Setter Property="FontSize" Value="24"/>
                  <Setter Property="Width" Value="270"/>
                  <Setter Property="Foreground" Value="Gray"/>
                  <Setter Property="Margin" Value="0,5"/>
                </Style>
              </StackPanel.Resources>
    
          <TextBlock>
            <Run Text="Hourly Tariff:"/>
            <LineBreak/>
            <Run Text="{Binding SelectedZone.TariffPH}" Foreground="White"/>
          </TextBlock>
    
          <TextBlock>
            <Run Text="Hours Open:"/>
            <LineBreak/>
            <Run Text="{Binding SelectedZone.HoursOpen}" Foreground="White"/>
          </TextBlock>
    
          <TextBlock>
            <Run Text="Days Open:"/>
            <LineBreak/>
            <Run Text="{Binding SelectedZone.DaysOpen}" Foreground="White"/>
          </TextBlock>
    
          <TextBlock>
            <Run Text="Parking Restrictions:"/>
            <LineBreak/>
            <Run Text="{Binding SelectedZone.Restrictions}" Foreground="White"/>
          </TextBlock>
    
        </StackPanel>
    

    ADDENDUM: Just noticed you had your StackPanel's Horizontal. For the Same effect just remove the <LineBreak/> lines and they'll be horizontal.