#419 – How Cell Sizes are Calculated when Using Star Sizing

You can use star sizing when setting the height of rows or width of columns in a Grid to distribute space in a Grid across multiple rows or columns.

Here’s an example.

    <Grid ShowGridLines="True">
    	<Grid.RowDefinitions>
    		<RowDefinition Height="Auto"/>
    		<RowDefinition Height="1*"/>
    		<RowDefinition Height="2*"/>
    		<RowDefinition Height="3*"/>
    	</Grid.RowDefinitions>

        <Label Grid.Row="0" Content="Auto-sized"/>
    	<Label Grid.Row="1" Content="1* row = 1/6 avail space" />
    	<Label Grid.Row="2" Content="2* row = 1/3 avail space" />
    	<Label Grid.Row="3" Content="3* row = 1/2 avail space" />
	</Grid>

The space allocated for each star-sized row is calculated as:

  • n / sum, where n = number preceding * for that row; sum = sum of all numbers preceding star-sized rows
  • Row is given n/sum of the total available space, after allocating space for Auto and Absolute sized rows

Advertisement

#418 – Star Sizing Allows Setting Row and Column Sizes Relative to Each Other

You can use star sizing when setting the height of rows or width of columns in a Grid to distribute space in a Grid across multiple rows or columns.

When you specify the size of a row or column with star sizing, you can specify the size simply as “*”, or you can specify a number followed by the star (e.g. 2*).  The number indicates the size of the row or column, relative to the other rows or columns.  (The value “*” is equivalent to “1*”).

In the example below, the second row’s height is specified as “2*”, indicating that it should always be twice the height of the first row.  (Or 2 / (1+2) = 2/3 of the total)

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

    	<Label Grid.Row="0" Content="I'm a 1* row" />
    	<Label Grid.Row="1" Content="I'm a 2* row" />
	</Grid>


#417 – Using Star Sizing to Distribute Space Evenly across Rows or Columns

You can use star sizing when setting the height of a row in a Grid or the width of a column.  After a Grid allocates space for rows and columns that are sized using absolute values or auto-sized to fit the row/column contents, it will distribute the remaining space in the Grid across rows and columns that use star sizing.

In the simplest case, if the height or width is specified as “*”, space is distributed evenly across all remaining rows/columns.

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

    	<Label Grid.Row="0" Content="Row 0 autosizes to this label" />
    	<Label Grid.Row="1" Content="1/3 of remaining space" />
    	<Label Grid.Row="2" Content="Another 1/3" />
    	<Label Grid.Row="3" Content="Final 1/3" />
	</Grid>



Star sizing is the default for a row’s height or a column’s width, if you do not explicitly set a height or width.

#416 – Setting Grid Rows and Columns to Autosize

When specifying the height of a row or the width of a column in a Grid, you can indicate that you want the row or column to automatically size to fit its content.  You can specify auto-sizing using the keyword “Auto” for the row height or column width.

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

    	<Label Grid.Row="0" Content="Row 0 autosizes to this label" />
    	<Label Grid.Row="1" Content="Row 1 takes up the remaining space" />
	</Grid>


#415 – Setting Grid Row Height and Column Width Properties to Absolute Values

You can set the height of a row or the width of a column in a Grid in one of three different ways.

One way to set a row’s height or a column’s width is to use an absolute value.  This mode is known in Blend as “Pixel sized” because you specify the size of the row or column in pixels.  (Actually, in device independent units, which map to pixels on a 96 dpi display).

    <Grid ShowGridLines="True">
    	<Grid.RowDefinitions>
    		<RowDefinition Height="52"/>
    		<RowDefinition/>
    	</Grid.RowDefinitions>

    	<Label Grid.Row="0" Content="Row 0 is 52 units high" />
    	<Label Grid.Row="1" Content="Row 1 takes up the remaining space" />
	</Grid>


A row or column whose size is set using an absolute number will retain its size when the size of the parent Grid changes.

#414 – Creating a Grid in Expression Blend

You can create a Grid element by editing XAML directly, in Visual Studio or Blend.  You can also use the designer in Blend to add a Grid and set its properties.

To add a Grid, find it in the Assets panel (under Controls | Panels).  Double-click to add it to the current window.

You’ll notice that a Grid element is added to the XAML (with no hard-coded dimensions).

You can add rows/columns to the Grid by clicking in the blue bars at the left and top of the Grid in the designer.  An orange triangle/line will appear, showing you the location of the new row or column.

XAML is updated.

You can click on the icon next to each row (column) to cycle between Star sized, Pixel sized and Auto sized for the row height (column width).

You can also set properties for the entire Grid from the Properties pane.

#413 – Creating a Grid from the Visual Studio Designer

You can create a Grid element by editing XAML directly, but you can also create the Grid and set its properties from within the designer in Visual Studio.

Start by finding the Grid control in the toolbox.

Double-click the entry in the toolbox, or left-click and drag it onto your design surface, to create a Grid element.  You’ll see the Grid show up in XAML and in the designer.

You can add rows and columns from within the designer by clicking on an empty area of the blue borders at the top and left of the Grid.  Small blue arrows will indicate the rows/columns added.

You can change row/column sizes by dragging the blue arrows.  You can also change the GridUnitType of a row/column, dictating how it will calculate its size.

Everything that you do will also be reflected in the XAML.


#412 – Three Ways to Set Row Height or Column Width in a Grid

You can set the height/width of rows/columns in a Grid using the Height and Width properties of the RowDefinition and ColumnDefinition elements.  You can specify these values in one of three different ways.

  • Auto – set height/width to fit the size of the contained element
  • numeric value – explicitly set height/width to specified number of device independent units (1/96th in)
  • * or n* – distribute remaining space proportionately across all rows/columns that set their height/width using the * mechanism

Below is an example showing these methods to set the width of four columns in a grid.

    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <!-- Contents of Grid go here -->
    </Grid>


The Chico column is set to 100 units wide, Harpo column set to fit content and all remaining space is split up between the Groucho and Zeppo columns.

#411 – Use HorizontalAlignment and VerticalAlignment to Position Child Elements within a Grid

By default, the HorizontalAlignment and VerticalAlignment properties of child elements in a Grid are set to Stretch.  This value indicates that the child element should be sized to fit the containing cell. In the example below, the labels and the button are all stretched to fit the containing cells.

You can set the alignment properties to other values, however.  HorizontalAlignment can be set to Stretch, Left, Center or RightVerticalAlignment can be set to Stretch, Top, Center or Bottom.

        <Label Grid.Row="0" Grid.Column="0" Content="Larry" Margin="5" Background="Lavender" HorizontalAlignment="Center" />
        <Label Grid.Row="0" Grid.Column="1" Content="Moe" Margin="5" Background="Magenta" VerticalAlignment="Center" />


The “Larry” label is still stretched vertically, but now centered horizontally.  The size of the label is also adjusted to fit the content.  The “Moe” label is still stretched horizontally, but now centered vertically.

#410 – Default Grid Row and Column Sizes

By default, all rows in a Grid are set to the same height, distributing the entire height of the Grid among all of its rows.  This is true if you do not explicitly set the height for any of the rows.

Similarly, if you don’t specify the width of any of the columns in the Grid, the entire width of the Grid is distributed evenly across all of its columns, so that each column is the same width.

    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="Larry" Margin="5" Background="Lavender"/>
        <Label Grid.Row="0" Grid.Column="1" Content="Moe" Margin="5" Background="Magenta"/>
        <Label Grid.Row="0" Grid.Column="2" Content="Curly" Margin="5" Background="Cornsilk"/>

        <Button Grid.Row="1" Grid.Column="1" Margin="5" Content="Do Eye Poke" />
    </Grid>