If you are a Web developer, probably most (but not all) of what this article is going to cover will be new to you. If you are a WinForms developer you have undoubtedly come across Panel classes before, and maybe even used some of the more sophisticated Panel sub classes, such as FlowLayoutPanel and TableLayoutPanel. You should also be familiar with WinForms properties such as Anchor and Dock. Sounds familiar? Well, the truth is that some of this knowledge will still be useful, but you will still have to do some learning. For you Web guys, the good news is that the XAML syntax is fairly similar to XHTML, so you shouldn’t have any trouble picking up this new way of creating UIs either.
Within WPF (at least the current version), Microsoft has provided a few Layout controls for developers/designers to use, most of which will be new ground to most of you, I imagine. These new layout controls will be the main focus of this article.
Canvas
The Canvas control is one of the easier layout controls to use. It is a simple X/Y position container. Where each of the contained (children) controls must specify the following four properties in order to be positioned within the parent Canvas control:
- Canvas.Left
- Canvas.Right
- Canvas.Top
- Canvas.Bottom
With these four properties in place, the control will be positioned using these values within the parent Canvas control.
What else do we need to know about a Canvas control and its children? Well actually that’s almost it, the only other thing to consider is that if the Canvas control is a simple X/Y position container, what’s to stop two child controls, overlapping, and which child control should be on top. Well that’s all taken care of by another dependency/attached property of the Canvas control. This is called the Canvas.ZIndex property, and this indicates which control should be on top. Basically the higher the Canvas.ZIndex value is, the more on top the control that declares this dependency/attached property will be. If no Canvas.ZIndex is declared for any of the children controls, the Canvas.ZIndex will be set to the order in which the children are added to the Canvas control.
Let’s see an example of this, shall we? The following picture shows a Canvas control with two children, one on top of the other.
StackPanel
The StackPanel control is also very easy to use. It simply stacks its contents, vertically or horizontally, using a single property, called Orientation.
Let’s see an example of this, shall we? The following picture shows a StackPanel control with two children, one on top of the other.
WrapPanel
The WrapPanel control, again, is very easy to use (are you seeing a pattern here? Layout is fairly OK in WPF), it simply wraps its contents.
Let’s see an example of this, shall we? The following picture shows a WrapPanel control with 10 children.
DockPanel
The DockPanel control is one of the most useful (IMHO) layout controls. It is the one that we would probably use as the base layout control that any new Window uses. Basically with a DockPanel control (or 2), we can achieve the sort of layout that has been the main layout for most applications we have ever seen. We can basically get a menu docked to the top, then a left/right main content area, and a status strip at the bottom. This is all thanks to a couple of properties on the DockPanel control. Basically we can control the docking of any of our child controls that is within a parent DockPanel control by the use of the following dependency/attached property.
- DockPanel.Dock
This property may be set to Left/Right/Top or Bottom. There is one further property exposed as a normal CLR property on the DockPanel control which is called LastChildFill which when set to true will make the last child control that was added to the DockPanel control, fill the remaining available space. This will override any DockPanel.Dock property that the child control may have already set.
Let’s see an example of this, shall we? The following picture shows a DockPanel control with two children, one docked to the top, and the other docked to fill the remaining available area.
Grid
The Grid control is by far, the most sophisticated WPF layout control there is (at present). It is sort of like an HTML table control, where you can specify rows and columns, and have cells that span multiple rows, or cells that span multiple columns. There is also a strange syntax which may be used for the Width/Height of Columns and Rows, which is known as the Star “*” notation, which is exposed through the use of the GridLength class. Think of this as being like a percentage of what’s left divider. For example I could have some markup such as:
<Grid.ColumnDefinitions>
<ColumnDefinition Width=”40″/>
<ColumnDefinition Width=”*”/>
<ColumnDefinition Width=”2*”/>
</Grid.ColumnDefinitions>
Where I have declared three Grid ColumnDefinition controls, where the first ColumnDefinition gets a fixed width of 40 pixels, and the remaining space is divided between the last two ColumnDefinition controls, where the last one gets twice as much as the second last one. This is the same principle for RowDefinition.
In order for child controls of a Grid control to tell the WPF layout system which cell they belong to, we simply use the following dependency/attached properties, which use a 0 based index.
- Grid.Column
- Grid.Row
And to specify how many rows or columns a cell should occupy, we simply use the following dependency/attached properties, which starts at 1.
- Grid.ColumnSpan
- Grid.RowSpan
By clever usage of a Grid control, you should almost be able to mimic any of the other layout controls. I’ll leave that as an exercise for the reader.
Let’s see an example of the Grid control, shall we? The following picture shows a Grid control with 3 Columns and 1 Row, where there are two children. The first child occupies Column 1, and the second child occupies Columns 2-3 as its Grid.ColumnSpan is set to 2.
Related Posts:



