Skip to main content

Panel

The Panel class is the base class for all controls that can contain multiple children. It provides the foundation for layout containers like Grid, StackPanel, Canvas, and DockPanel.

Namespace

Avalonia.Controls

Inheritance

Object → AvaloniaObject → Visual → Layoutable → Control → Panel

Properties

Children
Controls
Gets the collection of child controls.This is a Controls collection that supports adding, removing, and clearing children.
Background
IBrush
Gets or sets the panel’s background brush.The background is rendered behind all children.
IsItemsHost
bool
Gets whether the panel hosts items created by an ItemsPresenter.This is set internally when the panel is used as an ItemsPanel.

Methods

Render
void
Renders the panel and its background.Parameters:
  • context (DrawingContext): The drawing context
Override this to customize rendering.

Usage Examples

Basic Panel Usage

<Panel Background="LightGray">
    <Button Content="Button 1" />
    <Button Content="Button 2" Margin="0,50,0,0" />
    <Button Content="Button 3" Margin="0,100,0,0" />
</Panel>
The base Panel class doesn’t provide any layout logic - children overlap at position (0,0). Use derived classes like Grid or StackPanel for automatic layout.

Custom Panel

Create a custom panel by deriving from Panel:
using Avalonia;
using Avalonia.Controls;
using System;
using System.Linq;

public class VerticalStackPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        var totalHeight = 0.0;
        var maxWidth = 0.0;
        
        foreach (var child in Children)
        {
            child.Measure(availableSize);
            totalHeight += child.DesiredSize.Height;
            maxWidth = Math.Max(maxWidth, child.DesiredSize.Width);
        }
        
        return new Size(maxWidth, totalHeight);
    }
    
    protected override Size ArrangeOverride(Size finalSize)
    {
        var y = 0.0;
        
        foreach (var child in Children)
        {
            var childBounds = new Rect(
                0, 
                y, 
                finalSize.Width, 
                child.DesiredSize.Height
            );
            
            child.Arrange(childBounds);
            y += child.DesiredSize.Height;
        }
        
        return finalSize;
    }
}
Usage:
<local:VerticalStackPanel Background="AliceBlue">
    <TextBlock Text="Item 1" />
    <TextBlock Text="Item 2" />
    <TextBlock Text="Item 3" />
</local:VerticalStackPanel>

Managing Children in Code

using Avalonia.Controls;

var panel = new Panel();

// Add children
panel.Children.Add(new Button { Content = "Button 1" });
panel.Children.Add(new Button { Content = "Button 2" });

// Insert at specific index
panel.Children.Insert(1, new Button { Content = "Middle Button" });

// Remove a child
panel.Children.Remove(button1);

// Remove at index
panel.Children.RemoveAt(0);

// Clear all children
panel.Children.Clear();

// Get count
var count = panel.Children.Count;

// Iterate children
foreach (var child in panel.Children)
{
    // Process each child
}

Setting Background

<!-- Solid color -->
<StackPanel Background="LightBlue">
    <Button Content="Button" />
</StackPanel>

<!-- Gradient -->
<StackPanel>
    <StackPanel.Background>
        <LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
            <GradientStop Color="#4A90E2" Offset="0" />
            <GradientStop Color="#7B68EE" Offset="1" />
        </LinearGradientBrush>
    </StackPanel.Background>
    <Button Content="Button" />
</StackPanel>

Built-in Panel Types

Avalonia provides several specialized panel types:

Grid

Flexible grid layout with rows and columns

StackPanel

Stacks children horizontally or vertically

DockPanel

Docks children to edges (top, bottom, left, right)

Canvas

Absolute positioning with Left, Top, Right, Bottom

WrapPanel

Wraps children to next line when space runs out

UniformGrid

Evenly-sized cells in rows and columns

Creating Custom Panels

When creating custom panels, override these methods:

MeasureOverride

Calculate desired size:
protected override Size MeasureOverride(Size availableSize)
{
    // 1. Measure all children
    foreach (var child in Children)
    {
        child.Measure(availableSize);
    }
    
    // 2. Calculate and return desired size
    return CalculateDesiredSize();
}

ArrangeOverride

Position and size children:
protected override Size ArrangeOverride(Size finalSize)
{
    // Arrange each child with specific bounds
    foreach (var child in Children)
    {
        var bounds = CalculateChildBounds(child, finalSize);
        child.Arrange(bounds);
    }
    
    return finalSize;
}

Best Practices

Each panel type has specific strengths:
  • Grid: Complex layouts with aligned elements
  • StackPanel: Simple lists or toolbars
  • DockPanel: Application frames with sidebars/headers
  • Canvas: Absolute positioning for diagrams/games
Always call child.Measure() before accessing child.DesiredSize.
// Correct
child.Measure(availableSize);
var size = child.DesiredSize;

// Wrong: DesiredSize will be invalid
var size = child.DesiredSize;
For panels with many children, consider implementing virtualization to only create visible items.

See Also

Build docs developers (and LLMs) love