dotnet/wpf · error · InvalidOperationException

SR.Format(SR.CannotChangeAfterSealed, "Template")

Error message

SR.Format(SR.CannotChangeAfterSealed, "Template")

What it means

The Resources setter on FrameworkTemplate throws InvalidOperationException (SR.CannotChangeAfterSealed, "Template") when the template is sealed. A template's resource dictionary is frozen once the template is applied, because instantiated template trees rely on those resources being stable.

Solutions

  1. Populate template.Resources in XAML or in code before the template is assigned/used.
  2. Create a new template instance with the desired resources and assign it to the control's Template property.
  3. Put runtime-changeable resources in a higher-scope dictionary (Window/App Resources) instead of the template.

Example fix

// before
template.Resources.Add("brush", brush); // throws if sealed
control.Template = template;
// after
template.Resources.Add("brush", brush); // before sealing
control.Template = template;
Defensive patterns

Strategy: validation

Validate before calling

if (!template.IsSealed)
    template.Resources[key] = value;
else
    control.Template = BuildTemplateWithResource(key, value);

Prevention

When it happens

Trigger: Assigning template.Resources after the template was sealed (applied to a control or sealed during XAML load/layout).

Common situations: Adding resources to a ControlTemplate at runtime after it is assigned to a control's Template property; editing application resources nested inside a loaded template; trying to inject theme resources after first render.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/05b5942f009641a8. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkTemplate.cs:240

                        CanBeAccessedAcrossThreads = true
                    };
                }

                if ( IsSealed )
                {
                    _resources.IsReadOnly = true;
                }

                return _resources;
            }
            set
            {
                // Verify Context Access
                VerifyAccess();

                if ( IsSealed )
                {
                    throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, "Template"));
                }

                _resources = value;

                // A Template ResourceDictionary can be accessed across threads
                _resources?.CanBeAccessedAcrossThreads = true;
            }
        }

        ResourceDictionary IHaveResources.Resources
        {
            get { return Resources; }
            set { Resources = value; }
        }

        /// <summary>
        ///     Tries to find a Reosurce for the given resourceKey in the current
        ///     template's ResourceDictionary.

View on GitHub (pinned to 81131a70a4)