Layouts in WPF

StackPanel

Works the same way as FlowLayoutPanel in Windows Forms. In a vertical arrangement, each item fills the full width of the element it belongs to. Each element is exactly as tall as its content. The default arrangement is vertical.

XML
<StackPanel Orientation="Vertical">
    <!-- Vertical is the default -->
    <Label Background="Red">Red 1</Label>
    <Label Background="LightGreen">Green 1</Label>
    <StackPanel Orientation="Horizontal">
        <Label Background="Red">Red 2</Label>
        <Label Background="LightGreen">Green 2</Label>
        <Label Background="LightBlue">Blue 2</Label>
        <Label Background="Yellow">Yellow 2</Label>
        <Label Background="Orange">Orange 2</Label>
    </StackPanel>
    <Label Background="LightBlue">Blue 1</Label>
    <Label Background="Yellow">Yellow 1</Label>
    <Label Background="Orange">Orange 1</Label>
</StackPanel>


StackPanel

WrapPanel

In a vertical layout, the left side is filled first, and only then does it move to the right – whenever the next element no longer fits on the left. Likewise, in a horizontal layout the top row is filled first and it moves toward the bottom.

XML
<WrapPanel Orientation="Vertical">
    <Label Height="125" Background="Red">Red 1</Label>
    <Label Height="100" Background="LightGreen">Green 1</Label>
    <Label Height="125" Background="LightBlue">Blue 1</Label>
    <Label Height="50" Background="Yellow">Yellow 1</Label>
    <Label Height="150" Background="Orange">Orange 1</Label>
    <Label Height="100" Background="Red">Red 2</Label>
    <Label Height="150" Background="LightGreen">Green 2</Label>
    <Label Height="75" Background="LightBlue">Blue 2</Label>
    <Label Height="50" Background="Yellow">Yellow 2</Label>
    <Label Height="175" Background="Orange">Orange 2</Label>
</WrapPanel>


WrapPanel

DockPanel

Elements are stacked from the outside in. The last element fills the entire remaining area. Elements are placed inside the <DockPanel> tag and given the DockPanel.Dock attribute, which can take the following values: Top, Bottom, Left, Right. You can put 2 elements on the same DockPanel.Dock – they will be placed one after the other. If you do not specify DockPanel.Dock, the element fills the whole parent.

XML
<DockPanel>
    <Label DockPanel.Dock="Top" Height="100" Background="Red">Red 1</Label>
    <Label DockPanel.Dock="Left" Background="LightGreen">Green 1</Label>
    <Label DockPanel.Dock="Right" Background="LightBlue">Blue 1</Label>
    <Label DockPanel.Dock="Bottom" Background="LightBlue">Blue 2</Label>
    <Label DockPanel.Dock="Bottom" Height="50" Background="Yellow">Yellow 1</Label>
    <Label Width="100" Background="Orange">Orange 1</Label>
    <!-- default is to fill -->
    <Label Background="LightGreen">Green 2</Label>
</DockPanel>


DockPanel

Canvas

For placing an element at exact coordinates. Elements tell their parent where they should be using the Canvas.Left property, as well as Right, Top and Bottom. Top takes precedence over Bottom, and Left takes precedence over Right – this applies when you specify, for example, both Top and Bottom at once. In other words, everything is measured from point 0,0. If no size is specified, the element stretches to fit its content. It is enough to set just one Canvas.Direction value; the other one is automatically set to 0. Elements defined further down overlap elements defined above them.

XML
<Canvas>
    <!-- default coordinates 0,0 from top left; like WinForms -->
    <Label Background="Red">Red 1</Label>
    <Label Canvas.Right="50" Background="LightGreen">Green 1</Label>
    <Label Canvas.Top="100" Canvas.Left="100" Background="LightBlue">Blue 1</Label>
    <Label Canvas.Bottom="166" Canvas.Right="237" Background="Yellow">Yellow 1</Label>
    <Label Canvas.Right="300" Canvas.Top="250" Background="Yellow">Yellow 2</Label>
    <Label Canvas.Right="50" Canvas.Bottom="50" Background="Orange">Orange 1</Label>
</Canvas>


Canvas

UniformGrid

Use it when you want a table with rows and columns of equal size. The more elements you add to this parent, the smaller each element becomes (all of them keeping the same size).

XML
<UniformGrid>
    <Label Background="Red">Red 1</Label>
    <Label Background="LightGreen">Green 1</Label>
    <Label Background="LightBlue">Blue 1</Label>
    <Label Background="Yellow">Yellow 1</Label>
    <Label Background="Orange">Orange 1</Label>
</UniformGrid>


UniformGrid

Grid

A user-defined grid. First you have to specify the columns and rows that the grid will have. Then you add the elements themselves, and for each one you should set Grid.Row and Grid.Column. Numbering starts at zero. If you specify nothing, index 0 is used. Here again, whatever is defined further down overlaps what is defined above it.

XML
<Grid>
    <!-- Using default column and row configurations -->
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Label Grid.Column="0" Grid.Row="0" Background="Red">Red 1</Label>
    <Label Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Background="LightGreen">Green 1</Label>
    <Label Grid.Column="0" Grid.Row="1" Background="LightBlue">Blue 1</Label>
    <Label Grid.Column="1" Grid.Row="1" Background="Yellow">Yellow 1</Label>
    <Label Grid.Column="0" Grid.Row="2" Background="Orange">Orange 1</Label>
</Grid>


Grid

Naturally, all of these layouts can be nested inside one another. I took the images and inspiration from http://web.archive.org/web/20250812130401/https://www.codeproject.com/Articles/30904/WPF-Layouts-A-Visual-Quick-Start . I hope the author of the original article won’t mind that I reworked it for my readers.

Categories

Leave a Reply