XAML 101: Borders, Margins, and Alignment

FacebookTwitterGoogle+Share

Source code for this sample on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/005_Borders_Margins_Alignment

In this post we will look at another control, and some other properties that can help us with layout. The new control for this post is the Border, and it is similar to the Grid, but it only has a single child and no rows or columns. You can think of it as a frame for another control.

Let’s modify the Grid in MainPage.xaml to look like this:

<Grid Background="Red">
    <Border Background="Cyan">
        <TextBlock Text="Border Content"/>
    </Border>
</Grid>

We have a Border with a TextBlock inside it. Running the app looks like this:

image

Notice that the Border fills the entire Grid (we don’t see any of the Red background of the Grid). This is because the HorizontalAlignment and VerticalAlignment properties default to “Stretch” to fit the container.  Changing the Border’s alignments:

<Border HorizontalAlignment="Left" VerticalAlignment="Top" Background="Cyan">
    <TextBlock Text="Border Content"/>
</Border>

Now the Border is in the upper left corner:

image

It’s really hugging the edge there. We can give it some space using the Margin property:

<Border Margin="10,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Cyan">

And now it looks like this:

image

The Border’s Margin is set to “10,10,10,10”. These numbers represent the Left, Top, Right, and Bottom margins respectively. Note that this is a different order than margins in HTML where the order is Top, Right, Bottom, Left. We can also represent Margin as two numbers or a single number. In the case of two numbers, the Left and Right are set to the first number specified, and the Top and Bottom to the second number. If only one number is specified then all margins are set to this value. So we can change the Margin we specified above to this:

<Border Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Cyan">

If we move the Margin to the TextBlock instead of the Border, we get a slightly different look:

image

Now the background of the Border goes all the way to the edge, but the text is in the same position it was when the Margin was on the Border. There is another way to achieve this same result. We can set the Padding property on the Border:

<Border Padding="10" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Cyan">

Padding is available only on some controls, where Margin is available everywhere. With Padding, it has the same effect as putting a Margin around the content contained within the Border.

Let’s consider one more type of alignment, and that is text alignment. Let’s let the Border stretch to fill the control again, and set the TextAlignment property of the TextBlock:

<Border Padding="10" Background="Cyan">
    <TextBlock TextAlignment="Center" Text="Border Content"/>
</Border>

And we get something that looks like this:

image

Now we can get a very similar effect by setting the Border or the TextBlock to HorizontalAlignment=”Center” but there is a subtle but important difference. What happens when text is too big to fit in the available space horizontally? Change the Border and TextBlock to this:

<Border Padding="10" Background="Cyan">
    <TextBlock Text="This is a very long piece of text that won't fit on the page. Are you still reading this?"/>
</Border>

Running this and shrinking down the window as small as it will go, it looks like this:

image

Notice how the text gets cut off. That’s because text wrapping on the TextBlock is off by default. We can easily fix this:

<TextBlock TextWrapping="Wrap" Text="This is a very long piece of text that won't fit on the page. Are you still reading this?"/>

Now the app wraps the text:

image

No matter how we try, and whatever HorizontalAlignments we use, the second line will always be left justified. However if we set TextAlignment to “Center” then both lines will be centered:

image