dotnet/maui · error · Exception
ItemTemplate count has exceeded the limit of {ViewTypeCount}
Error message
ItemTemplate count has exceeded the limit of {ViewTypeCount}{Environment.NewLine}Please make sure to reuse DataTemplate objects What it means
ListViewAdapter.GetViewTypeForItemPath assigns each distinct DataTemplate a monotonically increasing integer key (stored in _templateToId, via _dataTemplateIncrementer) and throws if the key reaches ViewTypeCount. ViewTypeCount is Android's adapter view-type budget; exceeding it means the app is creating a new DataTemplate instance per item instead of reusing one.
Source
Thrown at src/Compatibility/Core/src/Android/Renderers/ListViewAdapter.cs:198
}
itemTemplate = selector.SelectTemplate(item, _listView);
}
// check again to guard against DataTemplateSelectors that return null
if (itemTemplate == null)
return DefaultItemTemplateId;
if (!_templateToId.TryGetValue(itemTemplate, out int key))
{
_dataTemplateIncrementer++;
key = _dataTemplateIncrementer;
_templateToId[itemTemplate] = key;
}
if (key >= ViewTypeCount)
{
throw new Exception($"ItemTemplate count has exceeded the limit of {ViewTypeCount}" + Environment.NewLine +
"Please make sure to reuse DataTemplate objects");
}
return key;
}
public override AView GetView(int position, AView convertView, ViewGroup parent)
{
Cell cell = null;
Performance.Start(out string reference);
ListViewCachingStrategy cachingStrategy = Controller.CachingStrategy;
var nextCellIsHeader = false;
if (cachingStrategy == ListViewCachingStrategy.RetainElement || convertView == null)
{
if (_listView.IsGroupingEnabled)
{View on GitHub (pinned to f377ff1c5e)
Solutions
- Cache DataTemplate instances — create them once (static fields, constructor) and return the same instance from the selector.
- Make DataTemplateSelector.OnSelectTemplate idempotent per type: store templates as fields and reuse them.
- Audit any code path that returns `new DataTemplate(...)` on the hot path and hoist it out.
Example fix
// before
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return item is Header ? new DataTemplate(typeof(HeaderViewCell)) : new DataTemplate(typeof(RowViewCell));
}
// after — reuse instances
private readonly DataTemplate _header = new DataTemplate(typeof(HeaderViewCell));
private readonly DataTemplate _row = new DataTemplate(typeof(RowViewCell));
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
=> item is Header ? _header : _row; Defensive patterns
Strategy: validation
Validate before calling
class SafeTemplateSelector : DataTemplateSelector
{
readonly Dictionary<Type, DataTemplate> _cache = new();
DataTemplate GetOrCreate<TCell>() where TCell : Cell
=> _cache.GetOrAdd(typeof(TCell), _ => new DataTemplate(typeof(TCell)));
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
=> item is Header ? GetOrCreate<HeaderCell>() : GetOrCreate<RowCell>();
} Prevention
- Never return `new DataTemplate(...)` per item from a selector — cache instances.
- Store templates as static/instance fields initialized once.
- Unit-test the selector to assert reference-equality reuse across calls.
- Monitor _templateToId growth in integration tests for large lists.
When it happens
Trigger: The app supplies a per-item DataTemplate factory that returns a NEW DataTemplate instance each call (e.g. inside a DataTemplateSelector returning `new DataTemplate(...)` per invocation), so _dataTemplateIncrementer climbs past ViewTypeCount.
Common situations: A DataTemplateSelector whose OnSelectTemplate returns `new DataTemplate(...)` rather than caching instances; building templates inside a loop or binding; using a lambda-based DataTemplate created per item.
Related errors
- ItemTemplate count has exceeded the limit of {ViewTypeCount}
- ItemTemplate count has exceeded the limit of {ViewTypeCount}
- View for cell must implement {nameof(INativeElementView)} to
- View for cell must implement INativeElementView to enable re
- ViewCell must have a {nameof(cell.View)}
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/08cf5c8a305dab46.
Report an issue: GitHub.