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
- Set each TriggerCondition.SourceName to StyleHelper.SelfName (or null-equivalent self reference) for style triggers.
- Bind the condition to a property of the styled element itself (e.g. IsMouseOver, IsChecked).
- 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
- Build style-trigger conditions with the single-argument Condition constructor (self source).
- Move SourceName-based conditions into ControlTemplate triggers.
- Audit reused trigger/condition objects for leftover SourceName values.
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
- SR.Format(SR.UnsupportedTriggerInStyle…
- SR.StyleTriggersCannotTargetTheTemplate
- SR.CannotChangeAfterSealed
- SR.ConditionCannotUseBothPropertyAndBinding
- SR.ConditionValueOfExpressionNotSupported
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)