XAML 101: Grid Sizing

FacebookTwitterGoogle+Share

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

In the last post we looked at Dependency Properties and a special version of those called Attached Properties. Some of the importance of these will become clearer later, but for now just treat them like you would any other property. Let’s see what other properties we can use on the powerful and flexible Grid control and its children for positioning.

In our “Hello World” app, in MainPage.xaml, we had a Grid with a couple of RowDefinitions and two TextBlocks. Let’s change things up a little to make it easier to see what is going on. Change the MainPage.xaml Grid to look like this:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid Background="Yellow">
            <TextBlock Text="Row 0"/>
        </Grid>
        <Grid Grid.Row="1" Background="LightBlue">
            <TextBlock Text="Row 1"/>
        </Grid>
        <Grid Grid.Row="2" Background="Orange">
            <TextBlock Text="Row 2"/>
        </Grid>
        <Grid Grid.Row="3" Background="Green">
            <TextBlock Text="Row 3"/>
        </Grid>
    </Grid>

Now our Grid has 4 nested Grids inside it, and each one is in a different row, and each has a TextBlock inside it. We can nest as many Grids and other controls inside each other as we want to get the layout we desire. By setting the Background property on each of these it is easy to see the space they take up. It looks like this:
image

So we can see that these rows each take up one quarter of the available space on the page. There are 3 different types of sizing for rows (and columns) in a grid. The default is “Star” sizing, which is what we see here. A little more about that later in this post. The next sizing type is “Auto” and we can see what this does by changing the Grid.RowDefinitions as follows:

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

And this is what it looks like in the running app:

image

The “Auto” size for rows sizes the row to the size of the largest element in that row. The same is true for Grid columns. Since we only have one element in each row, each row is sized to fit its content. The third type of sizing is “Pixel” sizing. Let’s change the row definitions like this:

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

Now the first row will be 70 pixels high, and the other rows will size to fit their contents, like this:

image

Now back to “Star” sizing. The name “Star” comes from the asterisk that is used to show that we want to use Star sizing. The following are all equivalent:

<RowDefinition/>
<RowDefinition Height="*"/>
<RowDefinition Height="1*"/>

The default height for a row definition is “1*”, and  the “1” is implied if not specified. The number before the Star determines how much of the available space will be reserved for the row. These numbers are only important in relation to each other, if you have more than one “Star sized” row in your Grid. How it works is that “Pixel sized” and “Auto sized” are given space first, and then the remaining space is split between the “Star sized” rows. All of the numbers for “Star sized” rows are added up, and then each is given a percentage based on its value. By combining star sizes with fixed sizes (auto or pixel) you can easily create some advanced layouts such as master-detail views. Let’s see how this works. Modify the Grid.RowDefinitions as follows:

<Grid.RowDefinitions>
    <RowDefinition Height="70"/>
    <RowDefinition Height="1*"/>
    <RowDefinition Height="1*"/>
    <RowDefinition Height="2*"/>
</Grid.RowDefinitions>

And the resulting app looks like this:

image

The first row gets 70 pixels, then the next 2 rows each get 25 percent of the remaining space, and the final row gets 50 percent of the remaining space. If you prefer percentages, you can do something like this with the same result:

<Grid.RowDefinitions>
    <RowDefinition Height="70"/>
    <RowDefinition Height=".25*"/>
    <RowDefinition Height=".25*"/>
    <RowDefinition Height=".50*"/>
</Grid.RowDefinitions>

That’s it for Grid sizing basics, remember that all of these same concepts apply to Grid.ColumnDefinitions except using the Width property instead of the Height.