Export (0) Print
Expand All

Object Positioning and Layout

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. Silverlight 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. The Visual Studio project template uses Grid as the default layout root.

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.

Cc189087.alert_note(en-us,VS.95).gifNote:

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.

Cc189087.alert_note(en-us,VS.95).gifNote:

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.

<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
Cc189087.JOLT_positioning_ovw1(en-us,VS.95).png
Cc189087.alert_note(en-us,VS.95).gifNote:

Silverlight rendering is not DPI dependent. Therefore, objects rendered on the screen and the coordinate systems 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.

<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
Cc189087.JOLT_positioning_ovw2(en-us,VS.95).png
Cc189087.alert_note(en-us,VS.95).gifNote:

In Silverlight-based applications that are embedded in HTML pages, the HTML element that hosts the Silverlight 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.

<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.

Cc189087.alert_note(en-us,VS.95).gifNote:

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.

<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.

Cc189087.stackpanel_verticle_basic(en-us,VS.95).png

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

<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. By default, children of a grid are placed in the first row and the first column. You can position objects in specific cells of the Grid by setting the Grid.Column and Grid.Row attached properties. The following example shows how to use the Grid to position some TextBlock objects, a Button, and a Rectangle inside a Grid.

<Grid Background="#DCDCDC" 
ShowGridLines="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <TextBlock Margin="2" 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" HorizontalAlignment="Left" Fill="Red"
           Width="200" Height="50"/>
    <Button Grid.Column="0" Grid.Row="2" Content="Stretched Button" />
    <Border Background="White" BorderThickness="5" Grid.Row="2" Grid.Column="1" Grid.RowSpan="2" >
    <TextBlock TextWrapping="Wrap">
        This TextBlock spans across two rows.
    </TextBlock>
    </Border>
    <TextBlock Margin="5" Grid.Row="3" Grid.Column="0">1st Column, 4th Row</TextBlock>
    <TextBlock Margin="5" Grid.Row="3" Grid.Column="2">3rd 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

In the proceeding example, Star sizing is used to distribute space proportionally. By default, Star is the height or width of a row or column, which means that the column or row receives a weighted proportion of the available space. In this example, there are 3 columns each using a single star size, so each column is allotted one-third of the width available to the grid.

Cc189087.alert_note(en-us,VS.95).gifNote:

The size of the grid must be constrained for Star sizing to work properly. Grid size can be constrained either by explicitly setting the Height and Width properties or by setting the HorizontalAlignment and VerticalAlignment values to Stretch on the Grid.

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. If the Grid does not have enough space to contain all the content, the content will be clipped starting at the bottom and on the right. In this example, the first and last rows use Auto sizing and are sized to contain the text.

By combining Star sizing with HorizontalAlignment and VerticalAlignment values 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. For more information on these properties, see Margin and Alignment Properties later in this topic.

The precise position of a FrameworkElement object within a panel can be specified by setting the Margin, HorizontalAlignment, and VerticalAlignment properties. In the following example, a part of a form is defined by using a Grid object.

<Grid x:Name="LayoutRoot" Background="Coral" Width="300" Height="100" ShowGridLines="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <TextBlock Grid.Column="0" Grid.Row="0" Text="First Name" />
    <TextBlock Grid.Column="0" Grid.Row="1" Text="Last Name" />
    <TextBox Grid.Column="1" Grid.Row="0" />
    <TextBox Grid.Column="1" Grid.Row="1" />

</Grid>


The following illustration shows how this code renders.

margin and alignment example

This layout looks a bit awkward because the elements are not aligned and there is no space between the objects and their container. Also, note that the two text boxes are stretched to fill their containers. This is because Stretch is the default value for the HorizontalAlignment and VerticalAlignment properties.

To position an object within its container area, use the HorizontalAlignment and VerticalAlignment properties. In the following example, the value Center is assigned to HorizontalAlignment and VerticalAlignment to position the TextBlock elements in the center of the Grid cells.

    <Grid x:Name="LayoutRoot" Background="Coral" Width="300" Height="100" ShowGridLines="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <TextBlock Grid.Column="0" Grid.Row="0" Text="First Name" HorizontalAlignment="Center" VerticalAlignment="Center" />
    <TextBlock Grid.Column="0" Grid.Row="1" Text="Last Name" HorizontalAlignment="Center" VerticalAlignment="Center" />
    <TextBox Grid.Column="1" Grid.Row="0" />
    <TextBox Grid.Column="1" Grid.Row="1" />

</Grid>


The following diagram shows the effect of the HorizontalAlignment and VerticalAlignment properties.

margin and alignment example

You can use the Margin property to create a margin of space between objects. 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 that has a margin specified as Margin="20, 10, 7, 8" would have a margin of 20 pixels on the left, 10 on the top, 7 on the right, and 8 on the bottom.

<Grid x:Name="LayoutRoot" Background="Coral" Width="300" Height="100" ShowGridLines="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <TextBlock Grid.Column="0" Grid.Row="0" Text="First Name" HorizontalAlignment="Center" VerticalAlignment="Center" />
    <TextBlock Grid.Column="0" Grid.Row="1" Text="Last Name" HorizontalAlignment="Center" VerticalAlignment="Center" />
    <TextBox Grid.Column="1" Grid.Row="0" Margin="15,10,15,10" />
    <TextBox Grid.Column="1" Grid.Row="1" Margin="15,10,15,10" />

</Grid>


The following illustration shows the effect of setting the Margin property.

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; instead, 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 Silverlight 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), it is generally best to leave the DOM Width/Height properties at 100% and exclude 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.

<UserControl x:Name="RootElement" x:Class="WindowResizingSample.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, Geometries, and Path Markup Syntax.

<Grid x:Name="LayoutRoot" 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" />

</Grid>


The following illustration shows how this code renders.

Positioning Line, Polyline, and Path objects

Cc189087.JOLT_positioning_ovw3(en-us,VS.95).gif
Cc189087.alert_note(en-us,VS.95).gifNote:

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).

<Grid x:Name="LayoutRoot" Background="White">
  <Rectangle Width="50" Height="50"
    Fill="RoyalBlue">
    <Rectangle.RenderTransform>
      <RotateTransform Angle="45" />
    </Rectangle.RenderTransform>
  </Rectangle>
</Grid>


The following illustration shows how this code is rendered.

A Rectangle rotated 45 degrees about the point (0, 0)
Cc189087.JOLT_local_772404290_graphicsmm_fe_rotated_about_upperleft_corner(en-us,VS.95).png

For more information about transforms and how to use them, see Transforms.

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.

<Grid x:Name="LayoutRoot" Background="White">
    <Canvas>

        <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>


</Grid>


The following illustration shows how this code renders.

Overlapping Ellipse objects
Cc189087.JOLT_positioning_ovw4(en-us,VS.95).gif

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.

<Grid x:Name="LayoutRoot" Background="White">
    <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>


</Grid>


The following illustration shows how this code renders.

Reversing the z-order of the Ellipse objects
Cc189087.JOLT_positioning_ovw5(en-us,VS.95).gif

Community Additions

Show:
© 2014 Microsoft