Printer Friendly Version      Send     
Click to Rate and Give Feedback
MSDN
MSDN Library
Web Development
Silverlight
 Object Positioning and Layout
Silverlight 2
Object Positioning and Layout (Silverlight 2)
[This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.]

This overview demonstrates how to control the position of objects (such as shapes, text, and media) in your Silverlight-based application.

This topic contains the following sections.

To position visual objects in your Silverlight-based application, you must put them in a Panel or container object. The parent Panel has defined layout behavior that determines how your object will be placed on the page. provides three container objects that derive from Panel.

The following table summarizes the available layout elements. Grid is the most flexible and powerful layout element.

Panel name

Description

Canvas

Defines an area within which you can explicitly position child elements by coordinates relative to the Canvas area.

Grid

Defines a flexible grid area consisting of columns and rows.

StackPanel

Arranges child elements into a single line that can be oriented horizontally or vertically.

In addition to positioning objects within container objects, you can also position container objects within other container objects. The following sections introduce you to positioning using panels.

Note:

To make it easier to see where your container objects are, you can set the Background or Fill of your objects to different colors. Naturally, when you are satisfied with how your objects are laid out you can remove these background colors or set them to something else.

Note:

Absolute positioning of objects by using a Canvas is conceptually the simplest form of positioning, but it is often not the best. Because absolute positioning does not take into account the size of the browser's window or browser resizing, panel objects are often a better choice. For more information, see Window Resizing later in this topic.

You control the positioning of objects inside the Canvas by specifying x and y coordinates. These coordinates are in pixels. The x and y coordinates are often 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 (x coordinate), and Canvas..::.Top specifies the object's distance from the top of the containing Canvas (y coordinate).

The following example 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 following illustration shows how this code renders inside the Canvas.

Positioning a rectangle inside the Canvas

Note:

rendering is not DPI dependent. Therefore, objects rendered on the screen and the coordinate system do not scale in response to monitor resolution. In addition, coordinates that are used by mouse events are not affected by monitor resolution.

You can nest Canvas objects and position them by using the Canvas..::.Left and Canvas..::.Top properties. When you nest objects, the coordinates used by each object are relative to its immediate containing Canvas. In the following example, the root (white) Canvas contains a nested (blue) Canvas that has Canvas..::.Left and Canvas..::.Top properties of 30. The nested blue Canvas contains a red rectangle that also has Canvas..::.Left and Canvas..::.Top values of 30.

XAML
<Canvas Width="300" Height="300" Background="White">
    <Canvas Width="250" Height="250" Canvas.Left="30" 
            Canvas.Top="30" Background="blue">

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

The following illustration shows how this code renders.

Nested objects

Note:

In Silverlight-based applications that are embedded in HTML pages, the HTML element that hosts the plug-in often has a specific width and height. Because of this, it is possible for objects to be positioned out of view. For example, if your host HTML element is only 300 pixels wide and you position an object 400 pixels to the right in your Silverlight-based application, your users will not be able to see the object.

In the previous example, using a nested Canvas creates the effect of a red rectangle bordered by a blue rectangle. A simpler and more powerful way of doing this is to use a Border object. The following example shows how to create a Border around some text.

XAML
<Border Background="Coral" Width="300" Padding="10" CornerRadius="20">
    <TextBlock FontSize="16">Text Surrounded by a Border</TextBlock>
</Border>

The following illustration shows how this code renders.

text surrounded by a border

You can specify basic properties of the Border by setting its Width, Height, BorderThickness and Background color. In addition, you can round out the border corners by setting the CornerRadius property, and you can position the object inside the Border by setting the Padding property.

Note:

A Border can have only one immediate child object. So, for example, if you want to put multiple objects within a Border, you must put a container object (such as a Canvas or StackPanel) inside the Border and then put the multiple objects inside the container object.

StackPanel is useful for the specific scenario where you want to arrange a set of objects in a vertical or horizontal list (for example, a horizontal or vertical menu or items). The following example shows how create a 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 following illustration shows how this code renders.

You can also create horizontal lists of items in a StackPanel by setting the Orientation property to Horizontal, as shown in the following example.

XAML
<StackPanel Orientation="Horizontal" 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 following illustration shows how this code renders.

basic horizontal stack panel

Grid is the most flexible and powerful container object provided by Silverlight. A Grid defines a flexible grid area that consists of columns and rows. You define the columns and rows of your Grid by using ColumnDefinition and RowDefinition respectively. You can then use the Grid..::.Column and Grid..::.Row attached properties to position objects within specific cells of the Grid. The example below shows how to use the Grid to position some TextBlock objects and a Rectangle inside a Grid.

XAML
<Grid Background="#DCDCDC" 
    Width="450"
    Height="200"
    HorizontalAlignment="Left"
    VerticalAlignment="Top"
    ShowGridLines="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <TextBlock Margin="5" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"
               TextWrapping="Wrap">
        This TextBlock is positioned in the first column and the 
        first row (column 0, row 0) and spans across all three columns (ColumnSpan 3).
    </TextBlock>
    <TextBlock Grid.Column="0" Grid.Row="1" Margin="5" FontWeight="Bold">Rectangle:</TextBlock>
    <Rectangle Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" Margin="5" Fill="Red"
               Width="250" Height="50"/>
    <TextBlock Margin="5" Grid.Row="3" Grid.Column="0" TextWrapping="Wrap">First Column, 4th Row</TextBlock>
    <TextBlock Margin="5" Grid.Row="3" Grid.Column="2" TextWrapping="Wrap">Third Column, 4th Row</TextBlock>
</Grid>

The following illustration shows how this code renders. Note that the ShowGridLines property of the Grid is set to true so that you can see the lines of the Grid. ShowGridLines is useful for visualizing where the Grid cells are, but because grid lines cannot be styled or customized, they are generally left out when layout design is finished.

grid sample

As you can see in the preceding example, the Margin property can be used to further control positioning within a Grid. In addition, the alignment properties HorizontalAlignment and VerticalAlignment can also be used to adjust positioning. For more information on these properties, see Margin and Alignment Properties later in this topic.

Each Grid object can contain one ColumnDefinitions object and one RowDefinitions object. Each RowDefinition and ColumnDefinition object inside the RowDefinitions and ColumnDefinitions elements defines a single row or column. The RowDefinition and ColumnDefinition objects also define the size of each row and column.

By default, rows and columns can take advantage of Star sizing to distribute remaining space proportionally. When Star is selected as the height or width of a row or column, that column or row receives a weighted proportion of the remaining available space. This value is expressed as * or n* when you use XAML. In the first case, the row or column would receive one fraction of the available space, while in the second case, the row or column would receive n fractions of the available space (where n is an integer). So if there were 3 rows each using a single star size, each row would be allotted one-third of the height available to the grid. By combining this technique to proportionally distribute space with a HorizontalAlignment and VerticalAlignment value of Stretch, it is possible to partition layout space by percentage of screen space. Grid is the only layout panel that can distribute space in this manner.

Rows and columns can also use Auto sizing, which distributes space evenly based on the size of the content that is within a column or row. Rows and columns take up the least amount of space necessary to accommodate the largest content within any cell contained in a given row or column.

When a FrameworkElement object is within a panel, the panel functions as a bounding box. The precise position of the object within that bounding box can be specified by setting the Margin, HorizontalAlignment, and VerticalAlignment properties. In the following example, a part of a form is defined by using two nested StackPanel objects.

XAML
<StackPanel Background="Coral">
    <StackPanel Orientation="Horizontal" >
        <TextBlock>First Name:</TextBlock>
        <TextBox Height="30" Width="180"></TextBox>
    </StackPanel>
    <StackPanel Orientation="Horizontal" >
        <TextBlock>Last Name:</TextBlock>
        <TextBox Height="30" Width="180"></TextBox>
    </StackPanel>
</StackPanel>

The following illustration shows how this code renders.

margin and alignment example

This layout looks a bit awkward because all the elements are right up against one another and there is no space between the objects and their container. You can use the Margin property to create a margin of space between objects. In the following example, the Margin property is set on the StackPanel objects and the TextBlock objects.

XAML
<StackPanel Background="Coral">
    <StackPanel Margin="10" Orientation="Horizontal" >
        <TextBlock Margin="4">First Name:</TextBlock>
        <TextBox Height="30" Width="180"></TextBox>
    </StackPanel>
    <StackPanel Margin="10" Orientation="Horizontal" >
        <TextBlock Margin="4">Last Name:</TextBlock>
        <TextBox Height="30" Width="180"></TextBox>
    </StackPanel>
</StackPanel>

The following diagram shows the effect of the Margin property.

margin and alignment example

The Margin property is of type Thickness, which means that you can specify different values for the left, top, right, and bottom margins. For example, in XAML, an object with a margin specified as Margin="10, 5, 20, 30" would have a margin of 10 pixels on the left, 5 on the top, 20 on the right, and 30 on the bottom.

You can also use the HorizontalAlignment and VerticalAlignment properties to position an object within its container area. In the following example, the HorizontalAlignment value of Center is used to position the child StackPanel elements in the center of their parent StackPanel.

XAML
<StackPanel Background="Coral">
    <StackPanel HorizontalAlignment="Center" Margin="10" Orientation="Horizontal" >
        <TextBlock Margin="4">First Name:</TextBlock>
        <TextBox Height="30" Width="180"></TextBox>
    </StackPanel>
    <StackPanel HorizontalAlignment="Center" Margin="10" Orientation="Horizontal" >
        <TextBlock Margin="4">Last Name:</TextBlock>
        <TextBox Height="30" Width="180"></TextBox>
    </StackPanel>
</StackPanel>

The following diagram shows the effect of the HorizontalAlignment property. Note that the child StackPanel objects have a light blue Background so that you can see the bounding boxes of those StackPanel objects.

margin and alignment diagram

Although absolute positioning of objects by using a Canvas is useful in some scenarios, it is typically a bad strategy in a browser window that will vary in size. Absolute positioning does not allow your objects to reflow on the page in response to browser window resizing; rather, objects remain positioned at their specified pixel positions.

StackPanel and Grid allow for reflow of content. The Grid object is the root element used by the Visual Studio template. Although the Grid is more complex to use than other Panel objects, it enables reflow of content and is flexible enough for you to create a variety of object layouts.

To get the best window resizing behavior, In addition to using Panel objects to position child objects within the plug-in, it is generally best to leave the DOM Width/Height properties at 100% and leave out any Width/Height declarations from the root element of your XAML file or the layout root element underneath. For example, in the following XAML, neither the root element nor the layout element has a width or height defined.

XAML
<UserControl x:Name="RootElement" x:Class="JustATest.Page"
    xmlns="http://schemas.microsoft.com/client/2007" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White">

    </Grid>
</UserControl>

Graphics such as the Path object, geometry objects, and shapes are specified using coordinates relative to their containing object. The following example shows the positioning syntax for some of these objects. For more information about paths, geometries, and other shapes, see Shapes and Drawing (Silverlight 2), Geometries (Silverlight 2), and Path Markup Syntax (Silverlight 2).

XAML
<Canvas Width="300" Height="300" Background="White">

    <!-- Simple line gives X and Y coordinates for the start
        and end of the line. -->
    <Line X1="280" Y1="10" X2="10" Y2="280"
        Stroke="Blue" StrokeThickness="5"/>

    <!-- A Polyline allows you to specify a number of X,Y coordinates
        to make a series of connected lines -->
    <Polyline Points="150, 150 150, 250 250, 250 250, 150"
        Stroke="Yellow" StrokeThickness="10"/>

    <!-- Path allows you to create more complex shapes including curves.
        Again, the shape of the Path is specified by coordinates. -->
    <Path Data="M 10,100 C 10,300 300,-200 250,100z"
        Stroke="Red" Fill="Orange"
        Canvas.Left="10" Canvas.Top="10" />

</Canvas>

The following illustration shows how this code renders.

Positioning Line, Polyline, and Path objects

Note:

You can use panels as well as Canvas to host graphics. In addition, you can often use margin and alignment properties to position graphics just like other types of objects.

Another way to change the position of an object is to apply a transform to it. You can use transforms to move the object, rotate it, skew its shape, change its size (scale), or a combination of these actions.

The following example shows a RotateTransform that rotates a Rectangle element 45 degrees about the point (0,0).

XAML
<StackPanel>
    <Rectangle Width="50" Height="50"
     Fill="RoyalBlue">
        <Rectangle.RenderTransform>
            <RotateTransform Angle="45" />
        </Rectangle.RenderTransform>
    </Rectangle>
</StackPanel>

The following illustration shows how this code is rendered.

A Rectangle rotated 45 degrees about the point (0,0)

For more information about transforms and how to use them, see Transforms (Silverlight 2).

So far, the discussion has focused on positioning objects in two-dimensional space. You can also position objects on top of one another. The z-order of an object determines whether an object is in front of or behind another overlapping object. By default, the z-order of objects within a Panel is determined by the sequence in which they are declared. Objects that are declared later appear in front of objects that are declared first. The following example creates three Ellipse objects. You can see that the Ellipse declared last (the lime-colored ellipse) is in the foreground, in front of the other two Ellipse objects.

XAML
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Ellipse 
        Canvas.Left="5" Canvas.Top="5" 
        Height="200" Width="200"
        Stroke="Black" StrokeThickness="10" Fill="Silver" />

    <Ellipse 
        Canvas.Left="50" Canvas.Top="50" 
        Height="200" Width="200"
        Stroke="Black" StrokeThickness="10" Fill="DeepSkyBlue" />

    <Ellipse 
        Canvas.Left="95" Canvas.Top="95" 
        Height="200" Width="200"
        Stroke="Black" StrokeThickness="10" Fill="Lime" />

</Canvas>

The following illustration shows how this code renders.

Overlapping Ellipse objects

You can change this behavior by setting the Canvas..::.ZIndex attached property on objects within the Panel. Higher values are closer to the foreground; lower values are farther from the foreground. The following example is similar to the preceding one, except that the z-order of the Ellipse objects is reversed. The System.Windows.Shapes..::.Ellipse that is declared first (the silver ellipse) is now in front.

XAML
<Canvas>
    <Ellipse 
        Canvas.ZIndex="3"
        Canvas.Left="5" Canvas.Top="5" 
        Height="200" Width="200"
        Stroke="Black" StrokeThickness="10" Fill="Silver" />

    <Ellipse 
        Canvas.ZIndex="2"
        Canvas.Left="50" Canvas.Top="50" 
        Height="200" Width="200"
        Stroke="Black" StrokeThickness="10" Fill="DeepSkyBlue" />

    <Ellipse 
        Canvas.ZIndex="1"
        Canvas.Left="95" Canvas.Top="95" 
        Height="200" Width="200"
        Stroke="Black" StrokeThickness="10" Fill="Lime" />

</Canvas>

The following illustration shows how this code renders.

Reversing the z-order of the Ellipse objects