In my last post we looked at how to use the stackpanel to build stacked layouts where controls either flow vertically or horizontally. In this article we will go over the Canvas control. The canvas is probably the most basic layout control. It simply provides a container in which child controls may be positioned absolutely.
In this example, we are using Silverlight 4 and Visual Studio Web Developer 2010.
Begin by creating a new Silverlight project called CanvasSample. Then modify MainPage.xaml to look like Figure 1. In the xaml we are adding a canvas and a text block inside the canvas. Pay close attention to the HorizontalAlignment and VerticalAlignment attributes. Notice we set them to center.
If you run the application you will see something that looks like Figure 2. Note that even though we set the TextBlock to center it is position in the upper left. Adding HorizontalAlignment and VerticalAlignment attributes to a control contained in a Canvas will not have an effect on its positioning.
Now modify the XAML to look like Figure 3. Note we have removed the HorizontalAlignment and VerticalAlignment attributes off of the TextBlock and added them to the Canvas.
Figure 3 – Canvas with Horizontal and Vertical Alignment set to center
You might expect that this XAML would result in the Canvas being auto sized to the size of its child controls, but this is not the case. If you run the app you will see something similar to Figure 4 below. Notice that the TextBlock is slightly off center and that our canvas’s red background doesn’t show. This is because the Canvas has a Width=0 and a height=0 because it will not auto size to it’s child controls even when Width=“Auto” is set. The TextBlock is positioned with its top left corner and the top left most part of the canvas hence the reason for being off center.
Now modify the XAML so that it looks like Figure 5 setting a fixed width and height on the canvas.
Figure 5 – Canvas with fixed width and height centered
Now if you run your application you should see something that looks like Figure 6. The canvas is now centered within its parent. Setting the width and height allows the canvas to be centered correctly
The next thing we need to explore is position child controls within the canvas itself. The canvas control is intended primarily for positioning child controls absolutely by giving each control an offset from the top and left of the canvas. If you are wanting to create a fluid or proportional layout you are probably better off using the StackPanel or Grid control. To set the X offset of a child control you add the Canvas.Left attribute on the control and specify a pixel value. To set the Y offset you use the Canvas.Top attribute.
It is also important to note that when you are positioning controls using absolute coordinates that controls might overlap. Each control has a Canvas.ZIndex property that specifies which controls will be drawn first. The ZIndex can be though of like a layer controls with lower ZIndexs will be drawn first and controls with higher ZIndexs will be drawn over controls with smaller ZIndexs. If no ZIndex is assigned controls will be “layered” in the order they appear in the XAML that is controls appearing last in XAML will have an implicitly higher ZIndex.
To try this out – modify your xaml again to look like Figure 7. Note how we have added two TextBlocks and set their Canvas.Top and Canvas.Left.
Figure 7 – Setting positioning of controls within a canvas
When you run the application it should look something like Figure 8. Notice how the white TextBlock is drawn over the black TextBlock giving a drop shadow look. Because we didn’t specify ZIndexs on the TextBlocks the one with the White Foreground is drawn on top because it appeared last in the XAML.
Now, if you give the first TextBlock a Canvas.ZIndex=“2” and the second one a Canvas.ZIndex=“1” as shown in Figure 9. You will see the black text drawn on top.
Figure 9 – Canvas child controls with ZIndexs set
Now run the app and you will see that the text blocks are drawn in a different order as in Figure 10.
In this post we have given a detailed look at the Silverlight Canvas layout control. To recap remember that HorizontalAlignment and VerticalAlignment will have no effect on child controls added to a Canvas. Also, remember that the Canvas will not auto size to the size of its children. The Canvas by default will scale to fit it’s parent container and you may set HorizontalAligment=“Stretch” or VerticalAlignment=“Stretch” to make the canvas stretch horizontally or vertically. Without an fixed width or height the HorizontalAlignment and VerticalAligment of the Canvas control might behave different that expected when set to something other than Stretch. With no width or height set the width and height will be 0 by default unless the alignments are set to stretch. Controls are positioned inside a canvas by specifying their absolute position using Canvas.Top and Canvas.Left.
© Copyright 2010 – SilverlightConnection.com