dotnet/maui · error · Exception

ItemTemplate count has exceeded the limit of {ViewTypeCount}

Error message

ItemTemplate count has exceeded the limit of {ViewTypeCount}
Please make sure to reuse DataTemplate objects

What it means

Thrown by the Android ListViewAdapter when the number of unique DataTemplate objects registered via GetItemTemplateId reaches ViewTypeCount. Android's adapter model allocates a fixed number of view types per ListView; creating a new DataTemplate per item instead of reusing a small set exhausts this budget.

Source

Thrown at src/Controls/src/Core/Compatibility/Handlers/ListView/Android/ListViewAdapter.cs:219

				}

				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;
		}

		// This is used by the `ListViewRenderer.GetDesiredSize` call to retrieve an already created ViewCellContainer
		// This helps us fake cell reuse so we aren't creating extra views during the measure pass.
		internal ConditionalFocusLayout GetConvertViewForMeasuringInfiniteHeight(int position)
		{
			if (_layoutsCreated.TryGetValue(position, out ConditionalFocusLayout foundValue))
				return foundValue;

			return null;
		}

		public override AView GetView(int position, AView convertView, ViewGroup parent)
		{

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Create the DataTemplate once and reuse it across all items (assign a single instance to ItemTemplate).
  2. In a DataTemplateSelector, return cached static DataTemplate fields, never allocate in SelectTemplate.
  3. Use a single template with bindings/triggers for per-item variation instead of N distinct templates.

Example fix

// before — allocates per item
listView.ItemTemplate = new DataTemplate(() => new ViewCell { View = BuildView(item) });

// after — single reusable template
var template = new DataTemplate(() =>
{
    var cell = new ViewCell();
    cell.View = new Label();
    cell.View.SetBinding(Label.TextProperty, "Name");
    return cell;
});
listView.ItemTemplate = template;
Defensive patterns

Strategy: validation

Validate before calling

// Allocate the DataTemplate once, reuse for all items
DataTemplate _shared = new DataTemplate(() =>
{
    var cell = new ViewCell { View = new Label() };
    cell.View.SetBinding(Label.TextProperty, "Name");
    return cell;
});
listView.ItemTemplate = _shared;

Prevention

When it happens

Trigger: Returning a new DataTemplate(() => new View()) for every item in HasListView.ItemTemplate (a factory that allocates per call). Using ItemTemplate = new DataTemplate(() => BuildCell(item)) inside a data-selectors that creates templates on the fly. Large lists with per-item distinct templates.

Common situations: Building DataTemplate inside GetCell or item-source enumeration rather than once. Using a DataTemplateSelector that returns brand-new DataTemplate instances instead of cached static ones. Misunderstanding that ItemTemplate should be a single shared template/selectors.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/7b8a22b2a45595f7. Report an issue: GitHub.