dotnet/wpf · error · InvalidOperationException

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

Error message

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

What it means

The DataTrigger.Binding setter throws InvalidOperationException once the trigger has been sealed (attached to a style/template that is in use). Styles seal their triggers to keep the runtime property-engine state immutable. Modify triggers before the style is applied.

Solutions

  1. Set Binding before assigning the style to any element or before the style is sealed
  2. Create a new Style/DataTrigger with the desired Binding and assign it to elements
  3. Clone or rebuild the style (new Style instance) rather than mutating the sealed one

Example fix

// before
style.Triggers.Add(trigger);
element.Style = style;
trigger.Binding = new Binding("IsEnabled"); // sealed -> throws
// after
trigger.Binding = new Binding("IsEnabled");
style.Triggers.Add(trigger);
element.Style = style;
Defensive patterns

Strategy: validation

Validate before calling

if (trigger.IsSealed) { trigger = CloneTrigger(trigger); trigger.Binding = newBinding; } else { trigger.Binding = newBinding; }

Type guard

bool CanModify(DataTrigger t) => !t.IsSealed;

Try / catch

try { trigger.Binding = newBinding; } catch (InvalidOperationException) { /* rebuild style/trigger */ }

Prevention

When it happens

Trigger: Setting DataTrigger.Binding after the containing Style/Template has been sealed (e.g. after Style.Seal or once the style is in use by elements).

Common situations: Mutating shared style resources at runtime; editing triggers of a style already applied via FrameworkElement.Style; hot-reload or theming code touching live styles.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/DataTrigger.cs:44

        /// </summary>
        [Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)] // Not localizable by-default
        public BindingBase Binding
        {
            get
            {
                // Verify Context Access
                VerifyAccess();

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

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

                _binding = value;
            }
        }

        /// <summary>
        ///     Value of the condition (equality check)
        /// </summary>
        [DependsOn("Binding")]
        [Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)] // Not localizable by-default
        public object Value
        {
            get
            {
                // Verify Context Access
                VerifyAccess();

View on GitHub (pinned to 81131a70a4)