dotnet/wpf · error · InvalidOperationException

SR.EventTriggerDoNotSetProperties

Error message

SR.EventTriggerDoNotSetProperties

What it means

EventTrigger.Seal() throws if the trigger contains Setter values (PropertyValues). Unlike property triggers, EventTriggers run actions in response to routed events and do not apply property setters; the library rejects any configured setters as a usage error.

Solutions

  1. Replace setters with EventTrigger Actions (e.g. BeginStoryboard or a TriggerAction-derived class) inside the EventTrigger.
  2. Move property setters to a regular Trigger or use a StateTrigger/VisualStateManager approach for state-based property changes.
  3. If the change should happen in response to an event, use an animation Storyboard targeting the property via BeginStoryboard.

Example fix

<!-- before -->
<EventTrigger RoutedEvent="ButtonBase.Click">
  <Setter Property="Opacity" Value="0.5" />
</EventTrigger>

<!-- after -->
<EventTrigger RoutedEvent="ButtonBase.Click">
  <BeginStoryboard>
    <Storyboard>
      <DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.5" />
    </Storyboard>
  </BeginStoryboard>
</EventTrigger>
Defensive patterns

Strategy: validation

Validate before calling

if (eventTrigger.PropertyValues.Count > 0)
    throw new InvalidOperationException("EventTrigger must not contain setters; use Actions instead.");

Try / catch

try { trigger.Seal(); }
catch (InvalidOperationException) { /* convert setters to BeginStoryboard/TriggerAction */ }

Prevention

When it happens

Trigger: Adding SetterBase items to EventTrigger via its SetterActions/property-values collection (or declaring <EventTrigger><Setter Property=.../></EventTrigger> in XAML) and then sealing the trigger when the style/template is applied.

Common situations: Copying a Trigger's setter syntax into an EventTrigger in XAML; programmatically adding setters to an EventTrigger assuming parity with Trigger/MultiTrigger; migration of legacy style code.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/EventTrigger.cs:213

        /// <summary>
        /// This method is used by TypeDescriptor to determine if this property should
        /// be serialized.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeActions()
        {
            return ( _actions != null && _actions.Count > 0 );
        }

        ///////////////////////////////////////////////////////////////////////
        // Internal members
        
        internal sealed override void Seal()
        {
            if( PropertyValues.Count > 0 )
            {
                throw new InvalidOperationException(SR.EventTriggerDoNotSetProperties);
            }

            // EnterActions/ExitActions aren't meaningful on event triggers.
            if( HasEnterActions || HasExitActions )
            {
                throw new InvalidOperationException(SR.EventTriggerDoesNotEnterExit);
            }

            if (_routedEvent != null && _actions != null && _actions.Count > 0)
            {
                _actions.Seal(this);  // TriggerActions need a link back to me to fetch the childId corresponding the sourceId string.
            }

            base.Seal(); // Should be almost a no-op given lack of PropertyValues
        }

        ///////////////////////////////////////////////////////////////////////
        // Private members

View on GitHub (pinned to 81131a70a4)