dotnet/maui · error · NotSupportedException
The Map.ItemTemplate property only supports DataTemplate. Se
Error message
The Map.ItemTemplate property only supports DataTemplate. Set the Map.ItemTemplateSelector property instead to use a DataTemplateSelector
What it means
The Map control separates its templating into two properties: ItemTemplate (for a single DataTemplate) and ItemTemplateSelector (for a DataTemplateSelector that chooses templates per-item). Assigning a DataTemplateSelector instance to ItemTemplate throws NotSupportedException because the internal CreatePinItems logic only handles uniform DataTemplate rendering, and silently ignoring the selector would produce wrong results.
Source
Thrown at src/Controls/Maps/src/Map.cs:287
if (oldItemsSource is INotifyCollectionChanged ncc)
{
ncc.CollectionChanged -= OnItemsSourceCollectionChanged;
}
if (newItemsSource is INotifyCollectionChanged ncc1)
{
ncc1.CollectionChanged += OnItemsSourceCollectionChanged;
}
_pins.Clear();
CreatePinItems();
}
void OnItemTemplatePropertyChanged(DataTemplate oldItemTemplate, DataTemplate newItemTemplate)
{
if (newItemTemplate is DataTemplateSelector)
{
throw new NotSupportedException(
$"The {nameof(Map)}.{ItemTemplateProperty.PropertyName} property only supports {nameof(DataTemplate)}." +
$" Set the {nameof(Map)}.{ItemTemplateSelectorProperty.PropertyName} property instead to use a {nameof(DataTemplateSelector)}");
}
_pins.Clear();
CreatePinItems();
}
void OnItemTemplateSelectorPropertyChanged()
{
_pins.Clear();
CreatePinItems();
}
void OnItemsSourceCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
e.Apply(
insert: (item, _, __) => CreatePin(item),View on GitHub (pinned to f377ff1c5e)
Solutions
- Use Map.ItemTemplateSelector instead of Map.ItemTemplate when you need per-item template selection.
- If you only need one template, assign it to Map.ItemTemplate directly.
- Verify the type of the object you are assigning: if it is a DataTemplateSelector subclass, use ItemTemplateSelector.
Example fix
// before map.ItemTemplate = new PinTemplateSelector(); // DataTemplateSelector subclass // after map.ItemTemplateSelector = new PinTemplateSelector();
Defensive patterns
Strategy: type-guard
Validate before calling
// Check before assigning
if (template is DataTemplateSelector)
map.ItemTemplateSelector = (DataTemplateSelector)template;
else
map.ItemTemplate = template; Type guard
static bool IsDataTemplateSelector(object template) => template is DataTemplateSelector;
Prevention
- Read the Map API: ItemTemplate is for a single DataTemplate, ItemTemplateSelector is for selectors.
- When refactoring from single template to selector, move the assignment to ItemTemplateSelector.
- Add a unit test asserting that assigning a DataTemplateSelector to ItemTemplate throws NotSupportedException.
When it happens
Trigger: Setting `map.ItemTemplate = new MyDataTemplateSelector()` where MyDataTemplateSelector derives from DataTemplateSelector. This can happen when a developer is unaware of the two-property split and assigns a selector to the simpler property.
Common situations: Copy-pasting a DataTemplateSelector from a ListView/CollectionView sample into Map.ItemTemplate instead of Map.ItemTemplateSelector. Refactoring code that previously used a single template to use a selector without moving the assignment. Misreading the API surface.
Related errors
- ItemTemplate count has exceeded the limit of {ViewTypeCount}
- You are using an instance of {nameof(DataTemplateSelector)}
- view
- Pin must have a Label to be added to a map
- XC0003
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/bbde335440f6938f.
Report an issue: GitHub.