dotnet/wpf · error · InvalidOperationException

SR.MissingTriggerProperty

Error message

SR.MissingTriggerProperty

What it means

StyleHelper.UpdateTables throws this while registering a property trigger: a TriggerAction/Setter whose Condition has a null Property was encountered. Every property-trigger condition must name a DependencyProperty to watch; the library throws InvalidOperationException at style (or template) attach time because a condition without a property can never be evaluated.

Solutions

  1. Assign Condition.Property to a valid DependencyProperty before the style is applied, e.g. cond.Property = UIElement.IsEnabledProperty
  2. In XAML ensure each <Condition Property="..." Value="..."/> has the Property attribute
  3. If a condition should not test a property, remove it and express the logic in the Setter or a data trigger
  4. Add a debug validation pass over style.Triggers before assigning the style to the element

Example fix

// before
var cond = new Condition { Value = true };
var trg = new Trigger(); trg.Conditions.Add(cond);
// after
var cond = new Condition { Property = UIElement.IsEnabledProperty, Value = true };
var trg = new Trigger(); trg.Setters.Add(new Setter(OpacityProperty, 0.5)); trg.Conditions.Add(cond);
Defensive patterns

Strategy: validation

Validate before calling

foreach (TriggerBase t in style.Triggers)
    if (t is Trigger tr)
        foreach (Condition c in tr.Conditions)
            if (c.Property == null) throw new InvalidOperationException("Condition.Property missing in trigger " + t.GetType().Name);

Try / catch

try { element.Style = style; } catch (InvalidOperationException ex) when (ex.Message.Contains("property")) { /* log style definition error */ }

Prevention

When it happens

Trigger: Attaching a Style/FrameworkTemplate whose Triggers contain a Trigger or MultiTrigger with a Condition whose Property is null — typically constructed in code with new Condition() and never assigning .Property, or XAML omitting the Property attribute while only supplying Value.

Common situations: Hand-building triggers in C# (e.g. condition = new Condition { Value = true };) and forgetting Property; deserializing BAML/XAML where the Property attribute was dropped; converter-generated styles from tooling emitting incomplete conditions.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/StyleHelper.cs:551

            case ValueLookupType.Trigger:
            case ValueLookupType.PropertyTriggerResource:
                {
                    if( propertyValue.Conditions != null )
                    {
                        // Record the current property as a dependent to each on of the
                        // properties in the condition. This is to facilitate the invalidation
                        // of the current property in the event that any one of the properties
                        // in the condition change. This will allow the current property to get
                        // re-evaluated.
                        for (int i = 0; i < propertyValue.Conditions.Length; i++)
                        {
                            int sourceChildIndex = propertyValue.Conditions[i].SourceChildIndex;
                            triggerSourceRecordFromChildIndex.EnsureIndex(sourceChildIndex);
                            ItemStructMap<TriggerSourceRecord> triggerSourceRecordMap = triggerSourceRecordFromChildIndex[sourceChildIndex];

                            if (propertyValue.Conditions[i].Property == null)
                            {
                                throw new InvalidOperationException(SR.MissingTriggerProperty);
                            }
                            int index = triggerSourceRecordMap.EnsureEntry(propertyValue.Conditions[i].Property.GlobalIndex);
                            AddPropertyDependent(childIndex, propertyValue.Property,
                                ref triggerSourceRecordMap.Entries[index].Value.ChildPropertyDependents);

                            // Store the triggerSourceRecordMap back into the list after it has been updated
                            triggerSourceRecordFromChildIndex[sourceChildIndex] = triggerSourceRecordMap;
                        }

                        // If value is a resource reference, add dependent on resource changes
                        if ((ValueLookupType)propertyValue.ValueType == ValueLookupType.PropertyTriggerResource)
                        {
                            AddResourceDependent(childIndex, propertyValue.Property, propertyValue.ValueInternal, ref resourceDependents);
                        }
                    }

                    // values in a Trigger may require per-instance storage
                    if ((ValueLookupType)propertyValue.ValueType != ValueLookupType.PropertyTriggerResource)

View on GitHub (pinned to 81131a70a4)