MaterialDesignInXAML/MaterialDesignInXamlToolkit · error · InvalidOperationException

Cannot get ThemeManager outside of a WPF application. Use

Error message

Cannot get ThemeManager outside of a WPF application. Use {nameof(ResourceDictionaryExtensions)}.{nameof(ResourceDictionaryExtensions.GetThemeManager)} on the appropriate resource dictionary instead.

What it means

GetThemeManager returns the IThemeManager stored in the application resources and applies the same Application.Current != null guard as the other PaletteHelper methods. When no WPF application is running it throws InvalidOperationException and points to ResourceDictionaryExtensions.GetThemeManager.

Solutions

  1. Call ResourceDictionaryExtensions.GetThemeManager on the relevant ResourceDictionary.
  2. Guard with `if (Application.Current is not null) ...` before calling.
  3. Obtain the manager from the dictionary you configured via SetTheme, which stores the ThemeManager.

Example fix

// before
var manager = new PaletteHelper().GetThemeManager();
// after
var manager = myResourceDictionary.GetThemeManager();
Defensive patterns

Strategy: type-guard

Validate before calling

if (Application.Current is null)
    return myResourceDictionary.GetThemeManager();
return new PaletteHelper().GetThemeManager();

Type guard

Application.Current is not null

Prevention

When it happens

Trigger: Calling PaletteHelper.GetThemeManager() outside a running WPF application (tests, designer, console, pre-startup).

Common situations: Subscribing to theme-change notifications in a unit test or design-time context; a service resolving the manager before the app starts.

Related errors


AI-assisted analysis of MaterialDesignInXAML/MaterialDesignInXamlToolkit@98edec3a0b (2026-08-13). Data as JSON: /api/errors/46a2a709d14ac704. Report an issue: GitHub.

Appendix: source

Thrown at src/MaterialDesignThemes.Wpf/PaletteHelper.cs:25

        if (Application.Current is null)
            throw new InvalidOperationException($"Cannot get theme outside of a WPF application. Use {nameof(ResourceDictionaryExtensions)}.{nameof(ResourceDictionaryExtensions.GetTheme)} on the appropriate resource dictionary instead.");
        return GetResourceDictionary().GetTheme();
    }

    public virtual void SetTheme(Theme theme)
    {
        if (theme is null) throw new ArgumentNullException(nameof(theme));
        if (Application.Current is null)
            throw new InvalidOperationException($"Cannot set theme outside of a WPF application. Use {nameof(ResourceDictionaryExtensions)}.{nameof(ResourceDictionaryExtensions.SetTheme)} on the appropriate resource dictionary instead.");

        GetResourceDictionary().SetTheme(theme);
        RecreateThemeDictionaries();
    }

    public virtual IThemeManager? GetThemeManager()
    {
        if (Application.Current is null)
            throw new InvalidOperationException($"Cannot get ThemeManager outside of a WPF application. Use {nameof(ResourceDictionaryExtensions)}.{nameof(ResourceDictionaryExtensions.GetThemeManager)} on the appropriate resource dictionary instead.");
        return GetResourceDictionary().GetThemeManager();
    }

    private static ResourceDictionary GetResourceDictionary()
        => Application.Current.Resources.MergedDictionaries.FirstOrDefault(x => x is IMaterialDesignThemeDictionary) ??
            Application.Current.Resources;

    /// <summary>
    /// Removes and readds resource dictionaries with static resource that will be re-evaluated with new theme brushes.
    /// This is primarily here for the obsolete theme brushes.
    /// </summary>
    private static void RecreateThemeDictionaries()
    {
        ResourceDictionary root = Application.Current.Resources;
        for (int i = 0; i < root.MergedDictionaries.Count; i++)
        {
            ResourceDictionary dictionary = root.MergedDictionaries[i];
            if (dictionary["MaterialDesign.Resources.RecreateOnThemeChange"] is bool recreateOnThemeChange && recreateOnThemeChange)

View on GitHub (pinned to 98edec3a0b)