dotnet/wpf · error · InvalidOperationException

SR.SourceNameNotSupportedForDataTriggers

Error message

SR.SourceNameNotSupportedForDataTriggers

What it means

MultiDataTrigger seals itself when its containing style/template is applied. During Seal(), each condition is checked and any condition with a SourceName set is rejected, because SourceName (element targeting) only makes sense for property triggers on named elements, not for data triggers that evaluate bound data. WPF throws InvalidOperationException to signal the trigger is configured in an unsupported way.

Solutions

  1. Remove the SourceName attribute from every Condition inside the MultiDataTrigger
  2. If element targeting is needed, use MultiTrigger with property conditions instead of MultiDataTrigger
  3. In code, do not set Condition.SourceName on conditions added to a MultiDataTrigger's Conditions collection

Example fix

<!-- before -->
<MultiDataTrigger>
  <Condition SourceName="okButton" Binding="{Binding IsReady}" Value="True"/>
</MultiDataTrigger>
<!-- after -->
<MultiDataTrigger>
  <Condition Binding="{Binding IsReady}" Value="True"/>
</MultiDataTrigger>
Defensive patterns

Strategy: validation

Validate before calling

// before applying the style
bool ok = multiDataTrigger.Conditions.Cast<Condition>().All(c => string.IsNullOrEmpty(c.SourceName));
if (!ok) throw new InvalidOperationException("MultiDataTrigger conditions must not set SourceName");

Type guard

static bool IsValidDataTriggerCondition(Condition c) =>
    c != null && string.IsNullOrEmpty(c.SourceName);

Prevention

When it happens

Trigger: Declaring a <MultiDataTrigger> (or adding via Conditions collection in code) whose Condition has SourceName set, e.g. <Condition SourceName="btn" Binding="..." .../>, then applying the style/template, which invokes MultiDataTrigger.Seal() at line 107-109.

Common situations: Copying a MultiTrigger condition into a MultiDataTrigger and forgetting to remove SourceName; hand-editing XAML converted from a MultiTrigger; tool-generated styles that emit SourceName unconditionally.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/MultiDataTrigger.cs:109

            }

            // Process the _setters collection: Copy values into PropertyValueList and seal the Setter objects.
            ProcessSettersCollection(_setters);

            if (_conditions.Count > 0)
            {
                // Seal conditions
                _conditions.Seal(ValueLookupType.DataTrigger);
            }

            // Build conditions array from collection
            TriggerConditions = new TriggerCondition[_conditions.Count];

            for (int i = 0; i < TriggerConditions.Length; ++i)
            {
                if (_conditions[i].SourceName != null && _conditions[i].SourceName.Length > 0)
                {
                    throw new InvalidOperationException(SR.SourceNameNotSupportedForDataTriggers);
                }

                TriggerConditions[i] = new TriggerCondition(
                    _conditions[i].Binding,
                    LogicalOp.Equals,
                    _conditions[i].Value);
            }

            // Set conditions array for all property triggers
            for (int i = 0; i < PropertyValues.Count; ++i)
            {
                PropertyValue propertyValue = PropertyValues[i];
                propertyValue.Conditions = TriggerConditions;
                switch (propertyValue.ValueType)
                {
                    case PropertyValueType.Trigger:
                        propertyValue.ValueType = PropertyValueType.DataTrigger;
                        break;

View on GitHub (pinned to 81131a70a4)