Skip to main content

ItemsRepeater

The ItemsRepeater displays repeating data from a bound collection. Unlike ListBox, it provides no built-in selection, scrolling, or chrome. Instead, it gives you full control over how items are laid out and rendered, while still supporting UI virtualization for large data sets.

You supply two things to an ItemsRepeater:

  • A data source via the ItemsSource property.
  • A data template via the ItemTemplate property that defines how each item looks.

By default, items are arranged in a vertical StackLayout. You can swap this for a horizontal StackLayout or a UniformGridLayout by setting the Layout property.

When to use ItemsRepeater

Use ItemsRepeater when you need a lightweight, virtualized list or grid without built-in selection. The table below compares it with related controls:

ControlSelectionVirtualizationBest for
ListBoxBuilt-inYesSelectable lists
ItemsControlNoneNo (by default)Small collections, custom layouts
ItemsRepeaterNoneYesLarge collections, custom layouts, performance

If you need selection behavior, consider wrapping items in a Button (see Handling click events below) or using ListBox instead.

Useful properties

You will probably use these properties most often:

PropertyDescription
ItemsSourceThe bound collection used as the data source.
ItemTemplateA DataTemplate that defines the visual structure for each item.
LayoutThe layout strategy for arranging items. Defaults to a vertical StackLayout.

Vertical list example

This example binds an observable collection of crockery items to an ItemsRepeater, with custom formatting provided by the data template:

<StackPanel Margin="20">
<TextBlock Margin="0 5">List of crockery:</TextBlock>
<ItemsRepeater ItemsSource="{Binding CrockeryList}">
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<Border Margin="0,10,0,0"
CornerRadius="5"
BorderBrush="Blue" BorderThickness="1"
Padding="5">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" />
<TextBlock Margin="5 0" FontWeight="Bold"
Text="{Binding Number}" />
</StackPanel>
</Border>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</StackPanel>
C# View Model
using AvaloniaControls.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace AvaloniaControls.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public ObservableCollection<Crockery> CrockeryList { get; set; }

public MainWindowViewModel()
{
CrockeryList = new ObservableCollection<Crockery>(new List<Crockery>
{
new Crockery("dinner plate", 12),
new Crockery("side plate", 12),
new Crockery("breakfast bowl", 6),
new Crockery("cup", 10),
new Crockery("saucer", 10),
new Crockery("mug", 6),
new Crockery("milk jug", 1)
});
}
}
}
C# Item Class
public class Crockery
{
public string Title { get; set; }
public int Number { get; set; }

public Crockery(string title, int number)
{
Title = title;
Number = number;
}
}
ItemsRepeater showing a vertical list of crockery items

Horizontal list example

You can display items horizontally by setting the Layout property to a horizontal StackLayout. Wrap the ItemsRepeater in a ScrollViewer so that items that overflow to the right remain accessible:

<StackPanel Margin="20">
<TextBlock Margin="0 5">List of crockery:</TextBlock>
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<ItemsRepeater ItemsSource="{Binding CrockeryList}" Margin="0 20">
<ItemsRepeater.Layout>
<StackLayout Spacing="40"
Orientation="Horizontal" />
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<Border Margin="0,10,0,0"
CornerRadius="5"
BorderBrush="Blue" BorderThickness="1"
Padding="5">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" />
<TextBlock Margin="5 0" FontWeight="Bold"
Text="{Binding Number}" />
</StackPanel>
</Border>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollViewer>
</StackPanel>
ItemsRepeater showing a horizontal list of crockery items with a scroll bar

Layout options

The Layout property accepts any object that derives from AttachedLayout. Avalonia ships with two built-in options:

StackLayout

Arranges items in a single line, either vertically (default) or horizontally.

PropertyDescription
OrientationVertical (default) or Horizontal.
SpacingThe distance in pixels between each item.

UniformGridLayout

Arranges items in a wrapping grid of equally-sized cells. The number of columns adjusts automatically based on the available width, making it ideal for responsive card layouts.

<ScrollViewer>
<ItemsRepeater ItemsSource="{Binding Products}">
<ItemsRepeater.Layout>
<UniformGridLayout MinItemWidth="250" MinItemHeight="180"
MinColumnSpacing="12" MinRowSpacing="12" />
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<Border Background="White" CornerRadius="8" Padding="16"
BorderBrush="#E5E7EB" BorderThickness="1">
<StackPanel Spacing="8">
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Text="{Binding Description}" TextWrapping="Wrap"
Foreground="Gray" />
</StackPanel>
</Border>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollViewer>
PropertyDescription
MinItemWidthMinimum width for each item.
MinItemHeightMinimum height for each item.
MinColumnSpacingMinimum horizontal spacing between items.
MinRowSpacingMinimum vertical spacing between items.
MaximumRowsOrColumnsMaximum number of rows or columns before wrapping.

Handling click events

Because ItemsRepeater has no built-in selection, you can handle clicks by wrapping each item in a Button that invokes a command on your view model:

<ItemsRepeater ItemsSource="{Binding Items}">
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<Button Command="{Binding $parent[ItemsRepeater].((vm:MainViewModel)DataContext).SelectCommand}"
CommandParameter="{Binding}"
Background="Transparent" Padding="0">
<Border Padding="12">
<TextBlock Text="{Binding Name}" />
</Border>
</Button>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>

You can also handle Tapped or PointerPressed events on individual items if you prefer an event-based approach rather than commands.

Scrolling and virtualization

ItemsRepeater does not include a built-in scroll viewer. To enable scrolling, wrap it in a ScrollViewer:

<ScrollViewer>
<ItemsRepeater ItemsSource="{Binding LargeCollection}">
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Margin="4" />
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollViewer>

When you place an ItemsRepeater inside a ScrollViewer, virtualization is enabled automatically. Only the items currently visible (plus a small buffer) are created, which keeps memory usage low and scrolling smooth even for collections with thousands of items.

See also