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
- Construct ButtonLayoutManager inside the renderer's constructor body (after base/init) where 'this' is a valid non-null IButtonLayoutRenderer.
- Ensure your custom renderer actually implements IButtonLayoutRenderer before passing it.
- 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
- Construct ButtonLayoutManager only after base renderer is initialised.
- Confirm the renderer implements IButtonLayoutRenderer.
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.