dotnet/wpf · error · InvalidOperationException

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

Error message

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

What it means

Style.TargetType setter throws InvalidOperationException (SR.CannotChangeAfterSealed "Style") when the style has already been sealed. A Style is sealed once it has been applied to elements or explicitly Seal()ed, after which its properties are immutable.

Solutions

  1. Create a new Style instance with the desired TargetType and assign that instead.
  2. If the style is in XAML resources, define a new keyed resource rather than mutating the applied one.
  3. If mutation is required, do it before the style is applied/sealed (before InitializeComponent completes or before the first assignment to a control's Style).
  4. Call CheckSeal-free approach: derive a new style with BasedOn and the new TargetType.

Example fix

// before
style.Seal();
style.TargetType = typeof(Button); // throws
// after
var newStyle = new Style(typeof(Button)) { BasedOn = style };
button.Style = newStyle;
Defensive patterns

Strategy: validation

Validate before calling

// Style has no public IsSealed check before WPF 4.x era APIs; guard by applying changes before first use
if (!styleApplied) style.TargetType = typeof(Button);

Try / catch

try { style.TargetType = t; }
catch (InvalidOperationException ex) when (ex.Message.Contains("sealed")) { style = new Style(t) { BasedOn = style }; }

Prevention

When it happens

Trigger: Assigning Style.TargetType after calling style.Seal() or after the style has been applied to a FrameworkElement/FrameworkContentElement (e.g. via Style property, implicit style, or BasedOn usage that forced sealing).

Common situations: Mutating a shared style retrieved from Resources that is already in use by rendered controls; changing TargetType in a window/page after InitializeComponent applied the resources; sharing one Style instance across windows and tweaking it later.

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/bbe253874119ee0a. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Style.cs:158

        [Localizability(LocalizationCategory.NeverLocalize)]
        public Type TargetType
        {
            get
            {
                // Verify Context Access
                VerifyAccess();

                return _targetType;
            }

            set
            {
                // Verify Context Access
                VerifyAccess();

                if (_sealed)
                {
                    throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, "Style"));
                }

                ArgumentNullException.ThrowIfNull(value);

                if (!typeof(FrameworkElement).IsAssignableFrom(value) &&
                    !typeof(FrameworkContentElement).IsAssignableFrom(value) &&
                    !(DefaultTargetType == value))
                {
                    throw new ArgumentException(SR.Format(SR.MustBeFrameworkDerived, value.Name));
                }

                _targetType = value;

                SetModified(TargetTypeID);
            }
        }

        /// <summary>

View on GitHub (pinned to 81131a70a4)