First Look: Silverlight 2.0 UI Controls
page 2 of 9
by Todd Anglin
Feedback
Average Rating: 
Views (Total / Last 10 Days): 51386/ 102

Layout Controls

Silverlight 2 beta 1 ships with three built-in layout controls: Canvas, StackPanel, and Grid. Before the beta release, Silverlight only provided a basic Canvas layout control, so the addition of the new StackPanel and Grid greatly improve your ability to flexibly (or precisely) control element position in your Silverlight application. If you've done any Windows development (especially with WPF) the "layout container" concept should be very familiar. If you're coming from the ASP.NET world (like me), it takes a little more getting used to.

In short, these layout containers help you position elements in your Silverlight application so that you don't have to manually set absolute positions for every element on your page. As your page is resized or as you add elements to your page, the layout containers intelligently shift things around based on their defined behavior- work you would have to do manually otherwise. Furthermore, these layout containers can be nested and extended, so they greatly improve your ability to build custom UI controls or more advanced auto-layout tools.

Canvas

The Canvas layout control is the most basic, and it has been around since the very first Silverlight versions. It provides the simple ability to absolutely position child elements relative to the canvas' top left corner. For example, let's say we have the following code (Listing 1) that adds a simple TextBlock to a Silverlight canvas:

Listing 1 - Canvas usage

<Canvas>
      <TextBlock Text="This is text on a blank canvas." 
            Canvas.Top="50" Canvas.Left="50" />
</Canvas>

When this code is rendered by the Silverlight plug-in, we'll see our text positioned 50 pixels from the top of the page and 50 pixels from the left of the page (Listing 2).

Listing 2 - Canvas with Textblock

The same result could have been achieved by simply adding a TextBlock to the default Silverlight UserControl (with no Canvas tag). That's because the UserControl provides a surrounding default canvas that can be used for element positioning if no other layout controls are used. All other layout controls are positioned relative to this default container. But be careful! The default container can only contain one element, so you'll almost always make a layout control the first element in your UserControl.

If I nest one canvas in another, the elements in each canvas will remain relative to the top left of their direct parent. In other words, elements in a canvas are not always absolutely positioned to the top left of the page. If the origin of the canvas moves, so do the relative locations of the contained elements on the page. Listing 3 illustrates this with a second canvas (colored red for clarity) added to first, but shifted 75 pixels down and to the right.

Listing 3 - Nested canvas

<Canvas>
      <TextBlock Text="This is text on a blank canvas." 
            Canvas.Top="50" Canvas.Left="50" />
      <Canvas Canvas.Top="50" Canvas.Left="50" Background="Red">
            <TextBlock Text="This is text on a blank canvas." 
                  Canvas.Top="50" Canvas.Left="50" />
      </Canvas>
</Canvas> 

Anybody notice what's missing in the image in Listing 3? If you said the red background that's "supposed" to be filling our second canvas, you're right. This highlights an important nuance of the Canvas control: while it will allow you to position items "in it", it won't automatically "expand" its background to hold the fill color. By default a canvas has a height and width of 0 and a transparent background. If we add height and width of 50 to our second canvas, we now see its position on the page (Listing 4).

Listing 4 - Canvas with visible background

StackPanel

The StackPanel enables you to easily position elements next to each other, both horizontally and vertically. In the web world, this is typically the type of layout implemented with HTML and CSS, where the next item on the page renders right where the other one stopped. It's less precise than the Grid layout, but much more flexible for scenarios where you may not know the user's resolution.

Let's see it in action. If you add two simple rectangles to a Silverlight canvas, by default they'll render overlapped (Listing 5). If a Stack Panel is used, though, the elements will automatically render next to each other. You can change the StackPanel's rendering mode by setting the Orientation property to either Horizontal or Vertical (default). Listing 7 shows the same rectangles in a StackPanel with Orientation set to Horizontal.

Listing 5 - Default positioning

 

Listing 6 - Position with a StackPanel

<StackPanel>
      <Rectangle Width="100" Height="50" Fill="Red"></Rectangle>
      <Rectangle Width="50" Height="25" Fill="Green"></Rectangle>
</StackPanel> 

Listing 7 - Horizontal StackPanel

<StackPanel Orientation="Horizontal">
      <Rectangle Width="100" Height="50" Fill="Red"></Rectangle>
      <Rectangle Width="50" Height="25" Fill="Green"></Rectangle>
</StackPanel>
 

Grid

Sure to confuse more than a few ASP.NET developers, Grid is not a datagrid. It's another layout control, most directly comparable to the HTML table. And as you would expect from a table-esque control, the Grid layout control allows you to precisely position your page elements in rows and columns. The Grid supports both fixed-width columns and "liquid" columns that fill the available space. Listing 8 shows a basic Grid layout control with 2 columns and 3 rows, with the second column set to a fixed width and the first liquid.

Listing 8 - Basic Grid layout control

<Grid x:Name="gridLayout1" Background="White">
      <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="300"></ColumnDefinition>
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
            <RowDefinition Height="300"></RowDefinition>
            <RowDefinition Height="200"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
      </Grid.RowDefinitions>
</Grid>

As you can see from the code in Listing 8, the "*" operator is used to define liquid dimensions in Silverlight. You can also gather that Grids are defined by collections of ColumnDefinitions and RowDefinitions defined in the XAML. Unlike HTML tables, though, content is not directly added to the column/row definitions. Instead, new controls are added within the Grid's opening and closing tags and are then positioned by setting Grid.Column and Grid.Row dependency properties (both of which will default to 0). Listing 9 shows the new Grid XAML with TextBlocks added to each cell.

Listing 9 - Grid with content

<Grid x:Name="gridLayout1" Background="White">
      <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="300"></ColumnDefinition>
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="100"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
      </Grid.RowDefinitions>
            <TextBlock Text="C1R1" Grid.Column="0" Grid.Row="0" />
            <TextBlock Text="C2R1" Grid.Column="1" Grid.Row="0" />
            <TextBlock Text="C1R2" Grid.Column="0" Grid.Row="1" />
            <TextBlock Text="C2R2" Grid.Column="1" Grid.Row="1" />
            <TextBlock Text="C1R3" Grid.Column="0" Grid.Row="2" />
            <TextBlock Text="C2R3" Grid.Column="1" Grid.Row="2" />
</Grid>

Grids also support a number of other advanced features, like column/row spanning (a concept borrowed from HTML tables), auto spacing, and even proportional sizing. The last feature is pretty cool because it allows you to set the width of a column to, let's say, "3*" and the column will automatically scale in proportion to the other columns (3:1 ratio). If only it were so elegant in HTML!


View Entire Article

User Comments

Title: how to embbed images in canvas ?   
Name: andrew
Date: 2008-10-11 12:39:36 PM
Comment:
Is there a way to put images in canvas based on logic ?






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2019 ASPAlliance.com  |  Page Processed at 2019-09-21 7:23:05 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search