dotnet/maui · error · ArgumentException

{nameof(element)} must be of type {typeof(IndicatorView).Nam

Error message

{nameof(element)} must be of type {typeof(IndicatorView).Name}

What it means

The Android IndicatorViewRenderer's explicit IVisualElementRenderer.SetElement implementation only accepts an IndicatorView element. It first checks for null (ArgumentNullException) then verifies the type with `element is IndicatorView`; any other VisualElement subtype triggers this ArgumentException. The renderer is hard-bound to a single control type because it wires IndicatorView-specific setup/teardown.

Source

Thrown at src/Compatibility/Core/src/Android/CollectionView/IndicatorViewRenderer.cs:79

			Measure(widthConstraint, heightConstraint);
			return new SizeRequest(new Size(MeasuredWidth, MeasuredHeight), new Size());
		}

		void IVisualElementRenderer.UpdateLayout()
		{
			Tracker?.UpdateLayout();
		}

		void IVisualElementRenderer.SetElement(VisualElement element)
		{
			if (element == null)
			{
				throw new ArgumentNullException(nameof(element));
			}

			if (!(element is IndicatorView))
			{
				throw new ArgumentException($"{nameof(element)} must be of type {typeof(IndicatorView).Name}");
			}

			var oldElement = IndicatorView;
			var newElement = (IndicatorView)element;

			TearDownOldElement(oldElement);
			SetUpNewElement(newElement);

			OnElementChanged(oldElement, newElement);

		}

		void IVisualElementRenderer.SetLabelFor(int? id)
		{
			if (_defaultLabelFor == null)
			{
				_defaultLabelFor = LabelFor;
			}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Verify the ExportRenderer(typeof(IndicatorView), typeof(IndicatorViewRenderer)) registration matches the element type actually passed.
  2. Ensure you are not reusing an IndicatorViewRenderer instance for a different control.
  3. If writing a subclass, override SetElement and keep the generic element type as IndicatorView.

Example fix

// before — wrong registration
[assembly: ExportRenderer(typeof(CollectionView), typeof(IndicatorViewRenderer))]
// after
[assembly: ExportRenderer(typeof(IndicatorView), typeof(IndicatorViewRenderer))]
Defensive patterns

Strategy: validation

Validate before calling

void AttachIndicator(IVisualElementRenderer renderer, VisualElement element)
{
    if (renderer is not IVisualElementRenderer) throw new ArgumentException("renderer incompatible");
    if (element is null) throw new ArgumentNullException(nameof(element));
    if (element is not IndicatorView)
        throw new ArgumentException($"Expected IndicatorView, got {element.GetType().Name}.", nameof(element));
    ((IVisualElementRenderer)renderer).SetElement(element);
}

Type guard

static bool IsIndicatorViewRendererFor(VisualElement e) => e is IndicatorView;

Prevention

When it happens

Trigger: Calling renderer.SetElement() (directly or via the MAUI/Xamarin.Forms registrar/handler pipeline) with an element that is not an IndicatorView — e.g. a wrong ExportRenderer registration, a custom handler swap, or programmatic renderer reuse with a different control.

Common situations: A mismatched ExportRenderer attribute pairing a non-IndicatorView control with IndicatorViewRenderer, or a custom renderer deriving from IndicatorViewRenderer but bound to a different element type. Rare in normal use; usually a registration/migration artifact.

Related errors


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