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
- Replace setters with EventTrigger Actions (e.g. BeginStoryboard or a TriggerAction-derived class) inside the EventTrigger.
- Move property setters to a regular Trigger or use a StateTrigger/VisualStateManager approach for state-based property changes.
- 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
- Remember EventTrigger only supports TriggerAction children (BeginStoryboard etc.), never Setter.
- Use property Trigger or VisualStateManager for state-driven property changes.
- Validate XAML trigger definitions when migrating between Trigger and EventTrigger.
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
- SR.EventTriggerDoesNotEnterExit
- Animation_NoTextChildren
- Animation_NoTextChildren
- SR.Animation_NoTextChildren
- SR.Animation_NoTextChildren
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 membersView on GitHub (pinned to 81131a70a4)