MaterialDesignInXAML/MaterialDesignInXamlToolkit · error · InvalidOperationException
This element has no adorner layer.
Error message
This element has no adorner layer.
What it means
`AdornerExtensions.AddAdorner<TAdorner>` fetches the `AdornerLayer` for a `UIElement` via `AdornerLayer.GetAdornerLayer(element)`. In WPF that returns null when the element is not yet part of a realized visual tree (e.g. no parent window/presentation source), so the extension throws `InvalidOperationException` rather than dereferencing null.
Source
Thrown at src/MaterialDesignThemes.Wpf/AdornerExtensions.cs:20
namespace MaterialDesignThemes.Wpf;
/// <summary>
/// This is a simple utility to add and remove a single adorner to an element
/// since there is no built-in way to do that in xaml.
/// <a href="https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/adorners-overview">See here</a>
/// </summary>
internal static class AdornerExtensions
{
public static void AddAdorner<TAdorner>(this UIElement element, TAdorner adorner) where TAdorner : Adorner
{
if (adorner is null)
{
throw new ArgumentNullException(nameof(adorner));
}
var adornerLayer = AdornerLayer.GetAdornerLayer(element)
?? throw new InvalidOperationException("This element has no adorner layer.");
adornerLayer.Add(adorner);
}
public static void RemoveAdorners<TAdorner>(this UIElement element) where TAdorner : Adorner
{
var adornerLayer = AdornerLayer.GetAdornerLayer(element);
var adorners = adornerLayer?.GetAdorners(element);
if (adorners is null)
{
return;
}
foreach (var adorner in adorners.OfType<TAdorner>())
{
adornerLayer!.Remove(adorner);
}View on GitHub (pinned to 98edec3a0b)
Solutions
- Defer `AddAdorner` until the element's `Loaded` event (or `OnContentRendered` of the window), guaranteeing an adorner layer exists.
- Check `AdornerLayer.GetAdornerLayer(element) != null` before calling, and retry on `LayoutUpdated`/`Loaded` if null.
- Ensure the element is parented in a visible window when you adorn it.
- Remove adorners in `Unloaded`/`Closed` to avoid stale references when the tree is torn down.
Example fix
// before
var layer = AdornerLayer.GetAdornerLayer(tb); // null in ctor -> throws later
myAdorner...; tb.AddAdorner(new MyAdorner(tb));
// after
tb.Loaded += (s, e) =>
{
if (AdornerLayer.GetAdornerLayer(tb) is { } layer)
layer.Add(new MyAdorner(tb));
}; Defensive patterns
Strategy: validation
Validate before calling
void SafeAddAdorner(UIElement element, Adorner adorner)
{
if (AdornerLayer.GetAdornerLayer(element) is { } layer)
layer.Add(adorner);
else
element.Loaded += (s, _) => AdornerLayer.GetAdornerLayer(element)?.Add(adorner);
} Type guard
static bool HasAdornerLayer(UIElement element)
=> AdornerLayer.GetAdornerLayer(element) is not null; Prevention
- Add adorners in Loaded, not in constructors/Initialized.
- Remove adorners in Unloaded/Closed to avoid stale references.
- Check GetAdornerLayer for null before adding.
When it happens
Trigger: Calling `element.AddAdorner(adorner)` on a `UIElement` that is not yet in the visual tree, before `Loaded`, after being removed from its parent, or on an element in a disconnected `UserControl`/popup.
Common situations: Attaching adorners in the constructor or `Initialized` instead of `Loaded`; adorning a templated element before template application; adorning an element whose window was closed; adorning inside a `Popup` before it is shown.
Related errors
- visualAncestry must contains at least one Visual control ins
- No loaded DialogHost instances.
- DialogHost is not open.
- Non primary hues provided.
- Entry {entry.Key} was not of type Color
AI-assisted analysis of MaterialDesignInXAML/MaterialDesignInXamlToolkit@98edec3a0b (2026-08-13).
Data as JSON: /api/errors/781f00893a1febb3.
Report an issue: GitHub.