dotnet/wpf · error · InvalidOperationException

SR.Format(SR.EventTriggerOnStyleNotAllowedToHaveTarget…

Error message

SR.Format(SR.EventTriggerOnStyleNotAllowedToHaveTarget, eventTrigger.SourceName)

What it means

WPF throws this when an EventTrigger declared inside a Style has a SourceName (TargetName) set. Styles apply to arbitrary instances of the styled type, so a style cannot route event trigger actions to a named element — only templates and FrameworkElement/FrameContent triggers can resolve names. Style.ProcessVisualTriggers rejects it at Seal() time with an InvalidOperationException.

Solutions

  1. Remove the SourceName/TargetName attribute from the EventTrigger in the style and target the styled element itself.
  2. If you need to animate a named child element, move the trigger into a ControlTemplate/DataTemplate instead of a Style.
  3. Use setter-based triggers (Trigger/MultiTrigger) in the style if the behavior can be expressed as property changes.

Example fix

<!-- before -->
<Style TargetType="Button">
  <Style.Triggers>
    <EventTrigger RoutedEvent="MouseEnter" SourceName="btn"/>
  </Style.Triggers>
</Style>

<!-- after -->
<Style TargetType="Button">
  <Style.Triggers>
    <EventTrigger RoutedEvent="MouseEnter"/>
  </Style.Triggers>
</Style>
Defensive patterns

Strategy: validation

Validate before calling

foreach (var t in style.Triggers.OfType<EventTrigger>())
    if (!string.IsNullOrEmpty(t.SourceName))
        throw new InvalidOperationException($"EventTrigger in Style cannot set SourceName '{t.SourceName}'; move it to a template.");

Type guard

bool isValidStyleEventTrigger(EventTrigger t) => string.IsNullOrEmpty(t.SourceName);

Try / catch

try { style.Seal(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("EventTrigger")) {
    // strip SourceName from style EventTriggers and re-seal
}

Prevention

When it happens

Trigger: Calling Style.Seal() (explicitly or implicitly when the style is first used) while its Triggers collection contains an EventTrigger whose SourceName property is a non-empty string.

Common situations: Copy-pasting an EventTrigger with TargetName="x" from a ControlTemplate into a <Style.Triggers> block; tooling or refactoring that moved triggers between a template and a style; writing <EventTrigger SourceName="Part_Grid" RoutedEvent="Mouse.MouseEnter"> directly in a style resource.

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

Appendix: source

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

                            {
                                Condition dataCondition = multiDataTrigger.Conditions[k];

                                StyleHelper.AddDataTriggerWithAction(trigger, dataCondition.Binding, ref this.DataTriggersWithActions);
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException(SR.Format(SR.UnsupportedTriggerInStyle, trigger.GetType().Name));
                        }
                    }

                    // Set things up to handle EventTrigger
                    EventTrigger eventTrigger = trigger as EventTrigger;
                    if( eventTrigger != null )
                    {
                        if( eventTrigger.SourceName != null && eventTrigger.SourceName.Length > 0 )
                        {
                            throw new InvalidOperationException(SR.Format(SR.EventTriggerOnStyleNotAllowedToHaveTarget, eventTrigger.SourceName));
                        }

                        StyleHelper.ProcessEventTrigger(eventTrigger,
                                                        null /*_childIndexFromChildID*/,
                                                        ref _triggerActions,
                                                        ref EventDependents,
                                                        null /*_templateFactoryRoot*/,
                                                        null,
                                                        ref _eventHandlersStore,
                                                        ref _hasLoadedChangeHandler);
                    }
                }
            }
        }

        /// <summary>
        ///     Serves as a hash function for a particular type, suitable for use in
        ///     hashing algorithms and data structures like a hash table

View on GitHub (pinned to 81131a70a4)