dotnet/wpf · error · InvalidOperationException

SR.Format(SR.TriggerOnStyleNotAllowedToHaveSource…

Error message

SR.Format(SR.TriggerOnStyleNotAllowedToHaveSource, conditions[k].SourceName)

What it means

Trigger conditions in a Style may only evaluate properties on the styled element itself. If a TriggerCondition has a SourceName other than StyleHelper.SelfName (i.e. it references a named element), ProcessVisualTriggers throws InvalidOperationException naming that SourceName, because styles have no element-name scope.

Solutions

  1. Set each TriggerCondition.SourceName to StyleHelper.SelfName (or null-equivalent self reference) for style triggers.
  2. Bind the condition to a property of the styled element itself (e.g. IsMouseOver, IsChecked).
  3. Move the trigger into the ControlTemplate if it must observe a named child element.

Example fix

// before
var condition = new Condition("btnChild", Button.IsPressedProperty, true); // SourceName set
// after
var condition = new Condition(Button.IsPressedProperty, true); // source = self
Defensive patterns

Strategy: validation

Validate before calling

// Before adding a Condition to a style trigger:
if (condition.SourceName != null && condition.SourceName != StyleHelper.SelfName)
    throw new InvalidOperationException($"Condition SourceName '{condition.SourceName}' not allowed in a Style.");

Type guard

static bool StyleConditionValid(Condition c) => c.SourceName == null || c.SourceName == StyleHelper.SelfName;

Try / catch

try { style.Seal(); }
catch (InvalidOperationException ex) { log.Error("Trigger condition references named element", ex); }

Prevention

When it happens

Trigger: Adding a trigger whose condition was built with SourceName="someElement" to Style.Triggers and sealing the style; reusing a template trigger's conditions in a style.

Common situations: Sharing trigger objects between ControlTemplate triggers (where SourceName is legal) and Style.Triggers; code-generated conditions that carry a source element name; copying XAML triggers from template to style.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

                    TriggerBase trigger = style._visualTriggers[i];

                    // Set things up to handle Setter values
                    for (int j = 0; j < trigger.PropertyValues.Count; j++)
                    {
                        PropertyValue propertyValue = trigger.PropertyValues[j];

                        // Check for trigger rules that act on container
                        if (propertyValue.ChildName != StyleHelper.SelfName)
                        {
                            throw new InvalidOperationException(SR.StyleTriggersCannotTargetTheTemplate);
                        }

                        TriggerCondition[] conditions = propertyValue.Conditions;
                        for (int k=0; k<conditions.Length; k++)
                        {
                            if( conditions[k].SourceName != StyleHelper.SelfName )
                            {
                                throw new InvalidOperationException(SR.Format(SR.TriggerOnStyleNotAllowedToHaveSource, conditions[k].SourceName));
                            }
                        }

                        // Track properties on the container that are being driven by
                        // the Style so that they can be invalidated during style changes
                        StyleHelper.AddContainerDependent(propertyValue.Property, true /*fromVisualTrigger*/, ref this.ContainerDependents);

                        StyleHelper.UpdateTables(ref propertyValue, ref ChildRecordFromChildIndex,
                            ref TriggerSourceRecordFromChildIndex, ref ResourceDependents, ref _dataTriggerRecordFromBinding,
                            null /*_childIndexFromChildID*/, ref _hasInstanceValues);
                    }

                    // Set things up to handle TriggerActions
                    if( trigger.HasEnterActions || trigger.HasExitActions )
                    {
                        if( trigger is Trigger )
                        {
                            StyleHelper.AddPropertyTriggerWithAction( trigger, ((Trigger)trigger).Property, ref this.PropertyTriggersWithActions );

View on GitHub (pinned to 81131a70a4)