Skip to main content
Version: 11.0.x

Custom ItemsPanel

All ItemsControls have an item container panel which is used to layout their items. It is possible to override the type of panel used by the control to achieve custom/alternative layouts of items in a control. This document provides some examples showcasing how and why you would do this.

Example

This example binds an observable collection of Rectangles (based on the Tile VM data) to an ItemsControl. ItemsControl.ItemPanel is set to a Canvas and we use a style to position the Rectangle within the Canvas.

<ItemsControl ItemsSource="{Binding TileList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="50" Height="50" Background="Yellow" Margin="3"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Fill="Green" Height="{Binding Size}" Width="{Binding Size}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Styles>
<Style Selector="ContentPresenter" x:DataType="vm:Tile">
<Setter Property="Canvas.Left" Value="{Binding TopX}"/>
<Setter Property="Canvas.Top" Value="{Binding TopY}"/>
</Style>
</ItemsControl.Styles>
</ItemsControl>
C# View Model
using AvaloniaControls.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace AvaloniaControls.ViewModels
{
public class MainWindowViewModel
{
public ObservableCollection<Tile> TileList { get; set; }

public MainWindowViewModel()
{
TileList = new ObservableCollection<Tile>(new List<Tile>
{
new Tile(10, 10, 10),
new Tile(10, 20, 20),
new Tile(10, 30, 30),
});
}
}
}
C# Item Class
public record Tile(int Size, int TopX, int TopY);