dotnet/maui · error · ArgumentNullException

renderer

Error message

renderer

What it means

ButtonLayoutManager is a helper that manages spacing/padding/insets for a UIButton-backed control (Button, ImageButton). Its constructor stores the renderer, subscribes to ElementChanged, and calls ImageElementManager.Init on the renderer's image renderer (line 52). A null renderer would NPE immediately, so it is rejected up front.

Source

Thrown at src/Compatibility/Core/src/iOS/Renderers/ButtonLayoutManager.cs:40

		Button _element;
		bool _preserveInitialPadding;
		bool _spacingAdjustsPadding;
		bool _borderAdjustsPadding;
		bool _collapseHorizontalPadding;

		UIEdgeInsets? _defaultImageInsets;
		UIEdgeInsets? _defaultTitleInsets;
		UIEdgeInsets? _defaultContentInsets;

		UIEdgeInsets _paddingAdjustments = new UIEdgeInsets();

		public ButtonLayoutManager(IButtonLayoutRenderer renderer,
			bool preserveInitialPadding = false,
			bool spacingAdjustsPadding = true,
			bool borderAdjustsPadding = false,
			bool collapseHorizontalPadding = false)
		{
			_renderer = renderer ?? throw new ArgumentNullException(nameof(renderer));
			_renderer.ElementChanged += OnElementChanged;
			_preserveInitialPadding = preserveInitialPadding;
			_spacingAdjustsPadding = spacingAdjustsPadding;
			_borderAdjustsPadding = borderAdjustsPadding;
			_collapseHorizontalPadding = collapseHorizontalPadding;

			ImageElementManager.Init(renderer.ImageVisualElementRenderer);
		}

		UIButton Control => _renderer?.Control;

		IImageVisualElementRenderer ImageVisualElementRenderer => _renderer?.ImageVisualElementRenderer;

		public void Dispose()
		{
			Dispose(true);
		}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Construct ButtonLayoutManager inside the renderer's constructor body (after base/init) where 'this' is a valid non-null IButtonLayoutRenderer.
  2. Ensure your custom renderer actually implements IButtonLayoutRenderer before passing it.
  3. Pass explicit preserve/spacing flags rather than relying on defaults that assume a live renderer.

Example fix

// before
private ButtonLayoutManager _layout = new ButtonLayoutManager(this);

// after
private ButtonLayoutManager _layout;
public MyButtonRenderer() { _layout = new ButtonLayoutManager(this); }
Defensive patterns

Strategy: validation

Validate before calling

if (renderer == null) throw new ArgumentNullException(nameof(renderer));
var mgr = new ButtonLayoutManager(renderer);

Type guard

static bool IsButtonLayoutRenderer(object r) => r is IButtonLayoutRenderer;

Prevention

When it happens

Trigger: Constructing new ButtonLayoutManager(null) - typically a ButtonRenderer/ImageButtonRenderer that passes 'this' before it is fully constructed, or a null due to a dependency-injection/custom-renderer override returning null.

Common situations: Custom Button/ImageButton renderers that instantiate ButtonLayoutManager in a field initializer or before the base renderer is assigned; incorrect hand-rolled renderer wiring.

Related errors


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