Primary APIs:
IDataTemplateIDataTemplate.Match(...)DataTemplatesDataTemplateExtensions.FindDataTemplate(...)DataTemplateFuncDataTemplateIRecyclingDataTemplateITypedDataTemplateITreeDataTemplateFuncTreeDataTemplateFuncTreeDataTemplate<T>TemplateContentItemsControl.ItemTemplateContentPresenter.ContentTemplateReference source files:
src/Avalonia.Controls/Templates/IDataTemplate.cssrc/Avalonia.Controls/Templates/DataTemplates.cssrc/Avalonia.Controls/Templates/DataTemplateExtensions.cssrc/Avalonia.Controls/Templates/FuncDataTemplate.cssrc/Avalonia.Controls/Templates/IRecyclingDataTemplate.cssrc/Avalonia.Controls/Templates/ITypedDataTemplate.cssrc/Avalonia.Controls/Templates/ITreeDataTemplate.cssrc/Avalonia.Controls/Templates/FuncTreeDataTemplate.cssrc/Avalonia.Controls/Templates/FuncTreeDataTemplate\1.cs`src/Avalonia.Controls/Templates/FuncTemplate\1.cs`src/Avalonia.Controls/Templates/FuncTemplate\2.cs`src/Avalonia.Controls/Templates/ITemplate\1.cs`src/Avalonia.Controls/Templates/ITemplate\2.cs`src/Avalonia.Controls/Templates/FuncTemplateNameScopeExtensions.cssrc/Markup/Avalonia.Markup.Xaml/Templates/DataTemplate.cssrc/Markup/Avalonia.Markup.Xaml/Templates/TreeDataTemplate.cssrc/Markup/Avalonia.Markup.Xaml/Templates/TemplateContent.cssrc/Avalonia.Controls/Presenters/ContentPresenter.cssrc/Avalonia.Controls/ItemsControl.csDataTemplateExtensions.FindDataTemplate(...) resolves in this order:
ContentTemplate/ItemTemplate) if Match succeeds.IDataTemplateHost.DataTemplates moving up ancestors.Application.DataTemplates via IGlobalDataTemplates).ContentPresenter then falls back to default templates when needed:
FuncDataTemplate.DefaultFuncDataTemplate.Access when access-key rendering is enabled.This precedence is critical when multiple templates can match the same data.
Avalonia does not use WPF DataTemplateSelector; use IDataTemplate instead.
Selector-style implementation:
using Avalonia.Controls;
using Avalonia.Controls.Templates;
public sealed class MessageTemplateSelector : IDataTemplate
{
public bool Match(object? data) => data is MessageViewModel;
public Control? Build(object? data)
{
return data switch
{
ErrorMessageViewModel vm => new ErrorMessageView { DataContext = vm },
WarningMessageViewModel vm => new WarningMessageView { DataContext = vm },
InfoMessageViewModel vm => new InfoMessageView { DataContext = vm },
MessageViewModel vm => new DefaultMessageView { DataContext = vm },
_ => null
};
}
}
Register in templates:
<Application.DataTemplates>
<local:MessageTemplateSelector />
</Application.DataTemplates>
Alternative selector pattern with FuncDataTemplate ordering:
var templates = new DataTemplates
{
new FuncDataTemplate<ErrorMessageViewModel>((vm, _) => new ErrorMessageView { DataContext = vm }),
new FuncDataTemplate<MessageViewModel>((vm, _) => new DefaultMessageView { DataContext = vm })
};
Important rule from DataTemplates:
ITypedDataTemplate in a DataTemplates collection must have DataType set.Example:
<Application.DataTemplates>
<DataTemplate x:DataType="vm:DashboardViewModel">
<views:DashboardView />
</DataTemplate>
</Application.DataTemplates>
Untyped custom IDataTemplate implementations can still participate without DataType.
ItemsControl behavior highlights:
ItemTemplate and DisplayMemberBinding are mutually exclusive.DisplayMemberBinding internally creates a FuncDataTemplate with a TextBlock.Recycling:
IRecyclingDataTemplate.Build(data, existing) for recyclable scenarios.FuncDataTemplate(..., supportsRecycling: true) opts in to reusing controls.Example:
listBox.ItemTemplate = new FuncDataTemplate<RowViewModel>(
(row, _) => new RowView { DataContext = row },
supportsRecycling: true);
For hierarchical data, use TreeDataTemplate/ITreeDataTemplate.
<TreeDataTemplate xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:MyApp.ViewModels"
x:DataType="vm:NodeViewModel"
ItemsSource="{CompiledBinding Children}">
<TextBlock Text="{CompiledBinding Title}" />
</TreeDataTemplate>
In 11.3.12, TreeDataTemplate.ItemsSource supports:
BindingCompiledBindingExtensionFunction-based tree templates:
FuncTreeDataTemplateFuncTreeDataTemplate<T>FuncTreeDataTemplate(Type type, Func<object?, INameScope, Control> build, Func<object?, IEnumerable> itemsSelector)FuncTreeDataTemplate(Func<object?, bool> match, Func<object?, INameScope, Control?> build, Func<object?, IEnumerable> itemsSelector)FuncTreeDataTemplate(Func<T, INameScope, Control> build, Func<T, IEnumerable> itemsSelector)FuncTreeDataTemplate(Func<T, bool> match, Func<T, INameScope, Control> build, Func<T, IEnumerable> itemsSelector)Template utility contracts often used with this space:
ITemplate<TControl>ITemplate<TParam, TControl>FuncTemplate<TControl>FuncTemplate<TParam, TControl>FuncTemplateNameScopeExtensions.RegisterInNameScope<T>(...)TemplateContent.Load(...)API-index compatibility note:
references/api-index-generated.md includes FuncTreeDataTemplate.ItemsSelector(object item) and TreeDataTemplate.ItemsSelector(object item) signatures.FuncTreeDataTemplate selector delegates and TreeDataTemplate.ItemsSource as primary configuration paths.For end-to-end advanced coverage of these APIs, see:
IDataTemplate.Match as fast and deterministic.x:DataType) for clarity and compiled-binding alignment.DataTemplates:
DataType.DisplayMemberBinding is also set (not allowed with ItemTemplate).ItemsSource binding is invalid or not one-way observable for children.