dotnet/wpf · error · InvalidOperationException

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

Error message

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

What it means

The ExecuteEnterActionsOnApply property setter on TriggerBase throws InvalidOperationException (CannotChangeAfterSealed, 'trigger') when set on a trigger whose owning Style/Template has been sealed. Once sealed, trigger configuration properties become immutable.

Solutions

  1. Set ExecuteEnterActionsOnApply when constructing the trigger, before applying the style
  2. Clone/rebuild the style with the desired value and reassign it
  3. Check trigger.IsSealed before writing the property

Example fix

// before
trigger.ExecuteEnterActionsOnApply = false; // throws after seal
// after
if (!trigger.IsSealed) { trigger.ExecuteEnterActionsOnApply = false; }
else { /* rebuild style with the flag set before apply */ }
Defensive patterns

Strategy: validation

Validate before calling

if (!trigger.IsSealed) { trigger.ExecuteEnterActionsOnApply = value; }

Type guard

static bool CanConfigure(TriggerBase t) => t != null && !t.IsSealed;

Try / catch

try { trigger.ExecuteEnterActionsOnApply = v; }
catch (InvalidOperationException ex) when (ex.Message.Contains("trigger")) { /* rebuild style */ }

Prevention

When it happens

Trigger: Setting trigger.ExecuteEnterActionsOnApply after the trigger's style/template was applied to a live element.

Common situations: Toggling trigger apply-behavior at runtime from code; adjusting shared styles after the window is loaded.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TriggerBase.cs:138

        /// If set to 'true', EnterActions will be executed immediately if the
        ///  conditions are met, before any "enter" change has occurred.
        /// </summary>

        // This is on the assumption that the "enter" change has occurred already.
        //  For example: <CheckBox IsChecked="true" /> the IsChecked property
        //  change occurred before the CheckBox Style/Template is applied.
        [DefaultValue(false)]
        public bool ExecuteEnterActionsOnApply
        {
            get
            {
                return _executeEnterActionsOnApply;
            }
            set
            {
                if (IsSealed)
                {
                    throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, "trigger"));
                }

                _executeEnterActionsOnApply = value;
            }
        }

        /// <summary>
        /// If set to 'true', ExitActions will be executed immediately if the
        ///  conditions are not met, before any "exit" change has occurred.
        /// </summary>
        [DefaultValue(false)]
        public bool ExecuteExitActionsOnApply
        {
            get
            {
                return _executeExitActionsOnApply;
            }
            set

View on GitHub (pinned to 81131a70a4)