Powered by

US - English
NEW! Silverlight 5 is available Learn More

Layout on the Screen

By Microsoft Silverlight Team|June 21, 2010|Level 200 : Novice

Summary

Silverlight provides a flexible layout system that enables you to specify how controls are positioned in the Silverlight application. This QuickStart helps you get started with the Silverlight layout system, the different types of layouts, and the various layout panels that you can use to position your controls.

This QuickStart contains the following sections:

Silverlight Layout System

Layout is the process of sizing and positioning objects in your Silverlight application. To position visual objects, you must put them in a Panel control or other container object. Silverlight provides various Panel controls, such as Canvas, StackPanel, and Grid, that serve as containers and enable you to position and arrange the controls.

The Silverlight layout system supports both an absolute layout and a dynamic layout. In an absolute layout, controls are positioned using explicit x/y coordinates (for example, by using a Canvas). In a dynamic layout, the layout container and the controls can be automatically sized and repositioned as the browser resizes (for example, by using a StackPanel or a Grid).

The following example shows how to design a layout using a Grid and a StackPanel. Some of the controls are created in XAML and some of the controls are added in code. Note that the ShowGridLines property of the Grid has been set to true. Grid lines help you debug and understand the layout behavior.

XAML

<Grid x:Name="LayoutRoot" Background="#DCDCDC" Width="400" Height="300" 
ShowGridLines="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="250" />
        <ColumnDefinition Width="150" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="2*" />
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="10" 
        FontWeight="Bold" Text="Contoso Corporation" HorizontalAlignment="Center" 
        VerticalAlignment="Center" />
    <Grid x:Name="FormLayoutGrid" Grid.Row="1" Grid.Column="0" 
    ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Text="First Name" Margin="10" 
            HorizontalAlignment="Left" VerticalAlignment="Center" />
        <TextBox Grid.Row="0" Grid.Column="1" Margin="10" />
        <TextBlock Grid.Row="1" Grid.Column="0" Text="Last Name" Margin="10" 
            HorizontalAlignment="Left" VerticalAlignment="Center" />
        <TextBox Grid.Row="1" Grid.Column="1" Margin="10" />
        <TextBlock Grid.Row="2" Grid.Column="0" Text="Address" Margin="10" 
            HorizontalAlignment="Left" VerticalAlignment="Center" />
        <TextBox Grid.Row="2" Grid.Column="1" Margin="10" />
    </Grid>
</Grid>

C#

public MainPage()
{
    InitializeComponent();
    LayoutDesign();
}

private void LayoutDesign()
{
    //Create Stackpanel for ListBox Control and its description
    StackPanel DeptStackPanel = new StackPanel();
    DeptStackPanel.Margin = new Thickness(10);

    LayoutRoot.Children.Add(DeptStackPanel);
    Grid.SetColumn(DeptStackPanel, 1);
    Grid.SetRow(DeptStackPanel, 1);

    TextBlock DeptListHeading = new TextBlock();
    DeptListHeading.Text = "Department";

    ListBox DeptList = new ListBox();
    DeptList.Items.Add("Finance");
    DeptList.Items.Add("Marketing");
    DeptList.Items.Add("Human Resources");
    DeptList.Items.Add("Payroll");

    DeptStackPanel.Children.Add(DeptListHeading);
    DeptStackPanel.Children.Add(DeptList);

    //Create StackPanel for buttons
    StackPanel ButtonsStackPanel = new StackPanel();
    ButtonsStackPanel.Margin = new Thickness(10);
    ButtonsStackPanel.Orientation = Orientation.Horizontal;
    ButtonsStackPanel.HorizontalAlignment = HorizontalAlignment.Center;

    LayoutRoot.Children.Add(ButtonsStackPanel);
    Grid.SetColumn(ButtonsStackPanel, 0);
    Grid.SetRow(ButtonsStackPanel, 2);
    Grid.SetColumnSpan(ButtonsStackPanel, 2);

    Button BackButton = new Button();
    BackButton.Content = "Back";
    BackButton.Height = 30;
    BackButton.Width = 100;

    Button CancelButton = new Button();
    CancelButton.Content = "Cancel";
    CancelButton.Height = 30;
    CancelButton.Width = 100;

    Button NextButton = new Button();
    NextButton.Content = "Next";
    NextButton.Height = 30;
    NextButton.Width = 100;

    ButtonsStackPanel.Children.Add(BackButton);
    ButtonsStackPanel.Children.Add(CancelButton);
    ButtonsStackPanel.Children.Add(NextButton);

    BackButton.Margin = new Thickness(10);
    CancelButton.Margin = new Thickness(10);
    NextButton.Margin = new Thickness(10);
}

Visual Basic

Public Sub New()
    InitializeComponent()
    LayoutDesign()
End Sub

Private Sub LayoutDesign()
    'Create Stackpanel for ListBox Control and its description 
    Dim DeptStackPanel As New StackPanel()
    DeptStackPanel.Margin = New Thickness(10)

    LayoutRoot.Children.Add(DeptStackPanel)
    Grid.SetColumn(DeptStackPanel, 1)
    Grid.SetRow(DeptStackPanel, 1)

    Dim DeptListHeading As New TextBlock()
    DeptListHeading.Text = "Department"

    Dim DeptList As New ListBox()
    DeptList.Items.Add("Finance")
    DeptList.Items.Add("Marketing")
    DeptList.Items.Add("Human Resources")
    DeptList.Items.Add("Payroll")

    DeptStackPanel.Children.Add(DeptListHeading)
    DeptStackPanel.Children.Add(DeptList)

    'Create StackPanel for buttons 
    Dim ButtonsStackPanel As New StackPanel()
    ButtonsStackPanel.Margin = New Thickness(10)
    ButtonsStackPanel.Orientation = Orientation.Horizontal
    ButtonsStackPanel.HorizontalAlignment = HorizontalAlignment.Center

    LayoutRoot.Children.Add(ButtonsStackPanel)
    Grid.SetColumn(ButtonsStackPanel, 0)
    Grid.SetRow(ButtonsStackPanel, 2)
    Grid.SetColumnSpan(ButtonsStackPanel, 2)

    Dim BackButton As New Button()
    BackButton.Content = "Back"
    BackButton.Height = 30
    BackButton.Width = 100

    Dim CancelButton As New Button()
    CancelButton.Content = "Cancel"
    CancelButton.Height = 30
    CancelButton.Width = 100

    Dim NextButton As New Button()
    NextButton.Content = "Next"
    NextButton.Height = 30
    NextButton.Width = 100

    ButtonsStackPanel.Children.Add(BackButton)
    ButtonsStackPanel.Children.Add(CancelButton)
    ButtonsStackPanel.Children.Add(NextButton)

    BackButton.Margin = New Thickness(10)
    CancelButton.Margin = New Thickness(10)
    NextButton.Margin = New Thickness(10)
End Sub

Absolute Layout

In an absolute layout, you arrange child elements in a layout panel by specifying their exact locations relative to their parent element. The child elements do not move when the parent panel is resized.

Silverlight provides a Canvas control to support absolute positioning. By default, when you create a new Silverlight application project, the root layout panel is a Grid. To create a layout based on absolute positioning, you must replace the Grid with a Canvas. You typically set the Height and the Width properties of the Canvas to Auto.

To position controls on a Canvas, you set the following attached properties on the control. When using the Silverlight Designer, these properties are updated when you drag controls on the design surface.

Dynamic Layout

In a dynamic layout, you arrange child elements by specifying how they should be arranged and how they should wrap relative to their parent. For example, you can arrange controls on a panel and specify that they should wrap horizontally. If the size of the parent element is reduced, the child elements move to the next row. As the parent element is enlarged, the child elements move to the previous row. Silverlight provides StackPanel and Grid panels that support dynamic layout.

Dynamic Sizing

When you create a Silverlight application, you set its size and the sizes of the controls on that application. You must decide how the Silverlight application and the controls behave if their content changes. For example, if you add a Label control to a Silverlight application, you can specify how the Label behaves if the text is translated into another language. In dynamic sizing, you configure controls so that they expand or contract automatically to fit their content.

The following table shows the properties that you can set to help you create dynamic layouts.

 
Property Values Applies to Notes
Width double, Auto, * UserControl, controls, grid columns. Use Auto and star (*) sizing for maximum flexibility. Star sizing applies only to grid columns.
Height double, Auto, * UserControl, controls, grid rows. Use Auto and star (*) sizing for maximum flexibility. Star sizing applies only to grid rows.
MinWidth double UserControl, controls, grid columns. Set to 0 for maximum flexibility.
MinHeight double UserControl, controls, grid rows. Set to 0 for maximum flexibility.
MaxWidth double, Infinity UserControl, controls, grid columns. Set to Infinity for maximum flexibility.
MaxHeight double, Infinity UserControl, controls, grid rows. Set to Infinity for maximum flexibility.
 

Auto and Star Sizing

Auto sizing is used to allow controls to fit their content, even if the content changes size. Star sizing is used to distribute available space among the rows and columns of a grid by weighted proportions. In XAML, star values are expressed as * (or n*). For example, if you have a grid with 4 columns, you could set the widths of the columns to the values shown in the following table.

 
Column_1 Auto The column will size to fit its content.
Column_2 * After the Auto columns are calculated, the column gets part of the remaining width. Column 2 will be one-half as wide as Column 4.
Column_3 Auto The column will size to fit its content.
Column_4 2* After the Auto columns are calculated, the column gets part of the remaining width. Column 4 will be two times as wide as Column 2.

For more information about Auto and star sizing, see the GridUnitType enumeration.

Panel Controls

The built-in layout panels in Silverlight are Canvas, StackPanel, and Grid.

Canvas

Canvas defines an area within which you can explicitly position child elements by coordinates relative to the Canvas area. Canvas is useful for scenarios where the UI elements contained within it never move.

You can position the control inside the Canvas by specifying x and y coordinates. The x and y coordinates are specified by using the Canvas.Left and Canvas.Top attached properties. Canvas.Left specifies the object's distance from the left side of the containing Canvas (the x-coordinate), and Canvas.Top specifies the object's distance from the top of the containing Canvas (the y-coordinate).

The following XAML shows how to position a rectangle 30 pixels from the left and 30 pixels from the top of a Canvas.

XAML

<Canvas Width="640" Height="480" Background="White">
    <Rectangle Canvas.Left="30" Canvas.Top="30"
        Fill="red" Width="200" Height="200" />
</Canvas>

The preceding XAML produces output that is similar to the following illustration.

Canvas

StackPanel

The StackPanel is a simple layout panel that arranges its child elements into a single line that can be oriented horizontally or vertically. You can use the Orientation property to specify the direction of the child elements. The default value for the Orientation property is Vertical. StackPanels are typically used in scenarios where you want to arrange a small subsection of the UI on your page.

The following xaml shows how to create a vertical StackPanel of items.

XAML

<StackPanel Margin="20">
    <Rectangle Fill="Red" Width="50" Height="50" Margin="5" />
    <Rectangle Fill="Blue" Width="50" Height="50" Margin="5" />
    <Rectangle Fill="Green" Width="50" Height="50" Margin="5" />
    <Rectangle Fill="Purple" Width="50" Height="50" Margin="5" />
</StackPanel>

The preceding XAML produces output that is similar to the following illustration.

StackPanel

Grid

The Grid control is the most flexible layout panel, and supports arranging controls in multi-row and multi-column layouts. You can specify a Grid's Row and Column definitions by using Grid.RowDefinitions and Grid.ColumnDefinitions properties that are declared immediately within the Grid control. You can position objects in specific cells of the Grid by using the Grid.Column and Grid.Row attached properties. You can distribute space within a column or a row using Auto or star sizing. Auto and star sizing is explained previously in this QuickStart. Content can span across multiple rows and columns by using the RowSpan and ColumnSpan attached properties.

Child elements of a Grid are drawn in the order in which they appear in markup or code. As a result, layered order (also known as z-order) can be achieved when elements share the same coordinates. For more information about z-order, see ZIndex.

The following XAML shows how to create a Grid with three rows and two columns. The height of the first and third rows is just large enough to contain the text. The height of the second row fills up the rest of the available height. The width of the columns is split equally within the available container width.

XAML

<Grid x:Name="LayoutRoot" Background="White" ShowGridLines="True">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition />
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <TextBox Text="First row and first column" Grid.Column="0" Grid.Row="0" />
    <TextBox Text="Third row and first column" Grid.Column="0" Grid.Row="2" />
    <Button Content="First row and second column" Grid.Column="1" Grid.Row="0" />
    <Button Content="Third row and second column" Grid.Column="1" Grid.Row="2" />
</Grid>

The preceding XAML produces output that is similar to the following illustration.

Grid

If you are creating a complex layout that is not easily achieved by using Canvas, StackPanel, or Grid, you can create a custom panel, which allows you to define layout behavior for the panel's children. To do this, derive from Panel and override its MeasureOverride and ArrangeOverride methods. For more information, see Custom Panels.

What's Next

Now that you have an idea of how to position content on the screen, let's move onto some more common UI components: Images in Silverlight.

See Also

Microsoft Silverlight Team

By Microsoft Silverlight Team, Silverlight is a powerful development platform for creating engaging, interactive user experiences for Web, desktop, and mobile applications when online or offline.

Comments (0)