StaggeredPanel
The StaggeredPanel arranges items into columns based on their height, filling the shortest column first. This creates a staggered "masonry" layout that is efficient for displaying items with varying heights, such as cards or images.
Basic Usage
The StaggeredPanel is typically used as the ItemsPanel of an ItemsControl or ListBox. Set the DesiredColumnWidth to control how many columns are created based on the available space.
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:nova="using:Nova.Avalonia.UI.Controls">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<nova:StaggeredPanel DesiredColumnWidth="200"
ColumnSpacing="10"
RowSpacing="10" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Height="{Binding Height}" Background="{Binding Brush}" CornerRadius="4">
<TextBlock Text="{Binding Title}" Margin="10" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</UserControl>
Configure Columns
The control automatically determines the number of columns by dividing the available width by the DesiredColumnWidth (plus spacing). It ensures at least one column is always present.
- DesiredColumnWidth: The target width for each column. The actual width may be slightly larger to fill the available space.
- ColumnSpacing: The horizontal space between columns.
- RowSpacing: The vertical space between items in the same column.
<nova:StaggeredPanel DesiredColumnWidth="150"
ColumnSpacing="20"
RowSpacing="20"
Padding="10">
<!-- Items... -->
</nova:StaggeredPanel>
Layout Logic
Items are added sequentially to the column with the minimum total height. This prevents large gaps and maintains a balanced visual weight across the panel.
Note
If the available width is infinite (e.g., inside a horizontal StackPanel or ScrollViewer), the panel will default to using the DesiredColumnWidth for every item, potentially creating a single horizontal row or one column per item depending on exact constraints. It is best used within a container that provides a constrained width (like a vertical ScrollViewer).
Properties
| Property | Type | Default | Description |
|---|---|---|---|
DesiredColumnWidth |
double |
250 |
The desired width for each column. |
ColumnSpacing |
double |
0 |
The distance between columns. |
RowSpacing |
double |
0 |
The distance between items in the same column. |
Padding |
Thickness |
0 |
The padding inside the panel border. |
Examples
Dynamic Resizing
The StaggeredPanel responds to window resizing by recalculating the number of columns.
<nova:StaggeredPanel DesiredColumnWidth="300" HorizontalAlignment="Stretch">
<!-- As the window widens, more columns will appear. -->
</nova:StaggeredPanel>
Direct Children
You can also use StaggeredPanel directly with children defined in XAML:
<nova:StaggeredPanel DesiredColumnWidth="120" ColumnSpacing="5" RowSpacing="5">
<Border Height="50" Background="Red" />
<Border Height="100" Background="Green" />
<Border Height="75" Background="Blue" />
<Border Height="120" Background="Orange" />
</nova:StaggeredPanel>
Virtualized Version
For large datasets (100+ items), use VirtualizedStaggeredLayout with ItemsRepeater for efficient scrolling:
<ScrollViewer>
<ItemsControl ItemsSource="{Binding LargeCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<nova:VirtualizingStaggeredPanel
DesiredColumnWidth="200"
ColumnSpacing="10"
RowSpacing="10" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Height="{Binding Height}" Background="{Binding Brush}" CornerRadius="4">
<TextBlock Text="{Binding Title}" Margin="10" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
VirtualizingStaggeredPanel Properties
| Property | Type | Default | Description |
|---|---|---|---|
DesiredColumnWidth |
double |
250 |
The desired width for each column. |
ColumnSpacing |
double |
0 |
The distance between columns. |
RowSpacing |
double |
0 |
The distance between items in the same column. |
Performance Features
The VirtualizingStaggeredPanel is optimized for large datasets:
- Container Recycling: Off-screen items are hidden and reused, not destroyed
- Minimal Allocations: Reusable collections avoid per-frame allocations
- 2x Viewport Buffer: Items above and below the viewport are pre-realized for smooth scrolling
- Pool Size Limit: Maximum 20 recycled containers per type to prevent memory bloat
Tip
For best performance with 500+ items, ensure your ItemTemplate is lightweight and avoid expensive bindings or effects on each item.