MahApps/MahApps.Metro · error · InvalidOperationException

OverlayBox can not be founded in this MetroWindow's template

Error message

OverlayBox can not be founded in this MetroWindow's template. Are you calling this before the window has loaded?

What it means

Thrown by MetroWindow.ShowOverlayAsync() when the internal overlayBox field (a Grid rendered behind dialogs) is null. The field is assigned during OnApplyTemplate, so calling the method before the window template has been applied/loaded means the control tree is not yet ready. This is a lifecycle/initialization-order error, not a configuration error.

Source

Thrown at src/MahApps.Metro/Controls/MetroWindow.cs:978

            }

            return (sb.Duration.HasTimeSpan && sb.Duration.TimeSpan.Ticks > 0)
                   || (sb.AccelerationRatio > 0)
                   || (sb.DecelerationRatio > 0)
                   || (animation.Duration.HasTimeSpan && animation.Duration.TimeSpan.Ticks > 0)
                   || animation.AccelerationRatio > 0
                   || animation.DecelerationRatio > 0;
        }

        /// <summary>
        /// Starts the overlay fade in effect.
        /// </summary>
        /// <returns>A task representing the process.</returns>
        public async System.Threading.Tasks.Task ShowOverlayAsync()
        {
            if (this.overlayBox is null)
            {
                throw new InvalidOperationException("OverlayBox can not be founded in this MetroWindow's template. Are you calling this before the window has loaded?");
            }

            if (this.IsOverlayVisible() && this.overlayStoryboard is null)
            {
                return;
            }

            this.Dispatcher.VerifyAccess();

            var sb = this.OverlayFadeIn?.Clone();

            if (!this.CanUseOverlayFadingStoryboard(sb, out var animation))
            {
                this.ShowOverlay();
                return;
            }

            this.overlayStoryboard = sb;

View on GitHub (pinned to 72099e310b)

Solutions

  1. Move the ShowOverlayAsync() call into the window's Loaded event handler (after the template has been applied), not the constructor.
  2. If using a custom ControlTemplate for MetroWindow, ensure it contains a Grid element named 'overlayBox' (PART) with appropriate panel ZIndex.
  3. Check this.IsLoaded before calling the overlay API, and defer with Dispatcher.BeginInvoke if not yet loaded.
  4. Do not call overlay methods from background threads; marshal to the UI thread first.

Example fix

// before
public MyWindow()
{
    InitializeComponent();
    this.ShowOverlayAsync(); // template not yet applied
}

// after
public MyWindow()
{
    InitializeComponent();
    this.Loaded += async (_, _) => await this.ShowOverlayAsync();
}
Defensive patterns

Strategy: validation

Validate before calling

if (!window.IsLoaded)
{
    // defer until Loaded
    window.Loaded += async (_, _) => await window.ShowOverlayAsync();
    return;
}
await window.ShowOverlayAsync();

Prevention

When it happens

Trigger: Calling ShowOverlayAsync() in the MetroWindow constructor, in the Loaded handler's early phase before OnApplyTemplate has run, or from a different thread before the window's visual tree is built. Also triggered when a custom window Style/ControlTemplate omits the 'PART_overlayBox' template part that the code-behind expects to find via GetTemplateChild.

Common situations: Developer calls await window.ShowOverlayAsync() right after constructing the window or inside the constructor. A custom MetroWindow style replaces the default template and forgets the overlay Grid named PART_overlayBox. Calling the overlay API from a background thread before the window has been shown.

Related errors


AI-assisted analysis of MahApps/MahApps.Metro@72099e310b (2026-08-13). Data as JSON: /api/errors/19b18415cda658f5. Report an issue: GitHub.