Layout controls are panels that arrange child elements according to specific layout logic. Avalonia provides several powerful layout controls adapted from WPF.
Grid
A flexible grid area that consists of columns and rows. The most versatile layout control.
Properties
- RowDefinitions: Collection of row definitions
- ColumnDefinitions: Collection of column definitions
- RowSpacing: Spacing between grid rows (double)
- ColumnSpacing: Spacing between grid columns (double)
- ShowGridLines: Display grid lines for debugging (bool)
Attached Properties
- Grid.Row: Row index for child element (int)
- Grid.Column: Column index for child element (int)
- Grid.RowSpan: Number of rows to span (int)
- Grid.ColumnSpan: Number of columns to span (int)
Example
<Grid RowDefinitions="Auto,*,Auto" ColumnDefinitions="200,*" ColumnSpacing="10" RowSpacing="10">
<!-- Header spanning all columns -->
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
Text="Application Header" FontSize="20" />
<!-- Sidebar -->
<Border Grid.Row="1" Grid.Column="0" Background="#F0F0F0">
<StackPanel Margin="10">
<Button Content="Option 1" />
<Button Content="Option 2" />
<Button Content="Option 3" />
</StackPanel>
</Border>
<!-- Main content -->
<ScrollViewer Grid.Row="1" Grid.Column="1">
<TextBlock Text="Main content area" />
</ScrollViewer>
<!-- Footer -->
<TextBlock Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"
Text="Status: Ready" />
</Grid>
var grid = new Grid
{
RowDefinitions = new RowDefinitions("Auto,*,Auto"),
ColumnDefinitions = new ColumnDefinitions("200,*"),
ColumnSpacing = 10,
RowSpacing = 10
};
var header = new TextBlock
{
Text = "Application Header",
FontSize = 20
};
Grid.SetRow(header, 0);
Grid.SetColumn(header, 0);
Grid.SetColumnSpan(header, 2);
grid.Children.Add(header);
Grid Sizing
Grid supports three sizing modes for rows and columns:
- Auto: Size to content
- Star (*): Proportional sizing (e.g.,
*, 2*, 3*)
- Fixed: Absolute pixel size (e.g.,
100, 200)
<Grid ColumnDefinitions="Auto,*,2*,100">
<!-- Auto: fits content -->
<!-- *: takes 1/3 of remaining space -->
<!-- 2*: takes 2/3 of remaining space -->
<!-- 100: fixed 100 pixels -->
</Grid>
StackPanel
Lays out children horizontally or vertically in a stack.
Properties
- Orientation: Layout direction -
Horizontal or Vertical (default: Vertical)
- Spacing: Space between child elements (double)
Example
<!-- Vertical Stack -->
<StackPanel Orientation="Vertical" Spacing="10">
<TextBlock Text="First Item" />
<TextBlock Text="Second Item" />
<TextBlock Text="Third Item" />
</StackPanel>
<!-- Horizontal Stack -->
<StackPanel Orientation="Horizontal" Spacing="5">
<Button Content="OK" />
<Button Content="Cancel" />
<Button Content="Apply" />
</StackPanel>
var stackPanel = new StackPanel
{
Orientation = Orientation.Vertical,
Spacing = 10
};
stackPanel.Children.Add(new TextBlock { Text = "First Item" });
stackPanel.Children.Add(new TextBlock { Text = "Second Item" });
stackPanel.Children.Add(new TextBlock { Text = "Third Item" });
DockPanel
Arranges children at the top, bottom, left, right, or center.
Properties
- LastChildFill: Whether the last child fills remaining space (bool, default:
true)
- HorizontalSpacing: Horizontal spacing between children (double)
- VerticalSpacing: Vertical spacing between children (double)
Attached Properties
- DockPanel.Dock: Dock position -
Left, Top, Right, or Bottom
Example
<DockPanel LastChildFill="True">
<!-- Top toolbar -->
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Background="#E0E0E0">
<Button Content="New" />
<Button Content="Open" />
<Button Content="Save" />
</StackPanel>
<!-- Bottom status bar -->
<TextBlock DockPanel.Dock="Bottom"
Text="Ready"
Padding="5"
Background="#F5F5F5" />
<!-- Left sidebar -->
<TreeView DockPanel.Dock="Left" Width="200" />
<!-- Center content (fills remaining space) -->
<TextBox AcceptsReturn="True" />
</DockPanel>
var dockPanel = new DockPanel
{
LastChildFill = true
};
var toolbar = new StackPanel
{
Orientation = Orientation.Horizontal,
Background = Brushes.LightGray
};
DockPanel.SetDock(toolbar, Dock.Top);
var statusBar = new TextBlock
{
Text = "Ready",
Padding = new Thickness(5)
};
DockPanel.SetDock(statusBar, Dock.Bottom);
dockPanel.Children.Add(toolbar);
dockPanel.Children.Add(statusBar);
Canvas
Displays children at arbitrary locations using absolute positioning.
Attached Properties
- Canvas.Left: Left position (double)
- Canvas.Top: Top position (double)
- Canvas.Right: Right position (double)
- Canvas.Bottom: Bottom position (double)
Example
<Canvas Background="#F0F0F0" Width="400" Height="300">
<!-- Position using Left/Top -->
<Ellipse Canvas.Left="50" Canvas.Top="50"
Width="100" Height="100"
Fill="#007ACC" />
<Rectangle Canvas.Left="200" Canvas.Top="100"
Width="150" Height="80"
Fill="#FF6B6B" />
<!-- Position using Right/Bottom -->
<TextBlock Canvas.Right="10" Canvas.Bottom="10"
Text="Bottom Right" />
</Canvas>
var canvas = new Canvas
{
Background = Brushes.LightGray,
Width = 400,
Height = 300
};
var ellipse = new Ellipse
{
Width = 100,
Height = 100,
Fill = Brushes.Blue
};
Canvas.SetLeft(ellipse, 50);
Canvas.SetTop(ellipse, 50);
canvas.Children.Add(ellipse);
Canvas is useful for custom drawing and absolute positioning, but should be avoided for general layouts as it doesn’t respond to window resizing.
Other Layout Controls
WrapPanel
Positions child elements in sequential order, wrapping to the next line when needed.
<WrapPanel Orientation="Horizontal">
<Button Content="Button 1" Width="100" />
<Button Content="Button 2" Width="100" />
<Button Content="Button 3" Width="100" />
<!-- Will wrap to next line if window is too narrow -->
</WrapPanel>
Arranges children in a grid with uniform cell sizes.
<UniformGrid Columns="3" Rows="2">
<Button Content="1" />
<Button Content="2" />
<Button Content="3" />
<Button Content="4" />
<Button Content="5" />
<Button Content="6" />
</UniformGrid>
Best Practices
- Use Grid for complex layouts - Grid is the most flexible for responsive designs
- Use StackPanel for simple lists - Ideal for buttons, menu items, or simple forms
- Use DockPanel for application frames - Perfect for toolbar/sidebar/content layouts
- Avoid Canvas for general layouts - Use only for custom drawing or games
- Combine layout panels - Nest different panel types for complex UIs
- Grid performs complex calculations during layout, but is optimized for most scenarios
- StackPanel is very efficient for simple linear layouts
- Avoid deep nesting of layout panels when possible
- Use VirtualizingStackPanel for long lists of items
See Also