dotnet/wpf · error · InvalidOperationException

SR.Format(SR.UnsupportedTriggerInStyle…

Error message

SR.Format(SR.UnsupportedTriggerInStyle, trigger.GetType().Name)

What it means

Style.Triggers only supports Trigger, MultiTrigger, DataTrigger, and MultiDataTrigger (plus EventTrigger handled separately). Any other TriggerBase-derived type (e.g. EventTrigger misuse aside, custom triggers) is rejected by ProcessVisualTriggers with InvalidOperationException naming the trigger's type.

Solutions

  1. Use only Trigger, MultiTrigger, DataTrigger, MultiDataTrigger (and EventTrigger for routed events) in Style.Triggers.
  2. If a custom trigger is required, implement it as a property with a converter used by a DataTrigger binding, or use a template trigger inside a ControlTemplate.
  3. Filter the trigger collection by type before adding to Style.Triggers.

Example fix

// before
style.Triggers.Add(myCustomTrigger); // custom TriggerBase subclass, throws
// after
var dataTrigger = new DataTrigger {
  Binding = new Binding("IsCustomState"),
  Value = true
};
dataTrigger.Setters.Add(new Setter(Control.BackgroundProperty, Brushes.Red));
style.Triggers.Add(dataTrigger);
Defensive patterns

Strategy: type-guard

Validate before calling

var allowed = new[] { typeof(Trigger), typeof(MultiTrigger), typeof(DataTrigger), typeof(MultiDataTrigger), typeof(EventTrigger) };
foreach (var t in triggers)
    if (!allowed.Contains(t.GetType()))
        throw new InvalidOperationException($"{t.GetType().Name} is not supported in Style.Triggers.");

Type guard

static bool IsStyleSupportedTrigger(TriggerBase t) =>
  t is Trigger or MultiTrigger or DataTrigger or MultiDataTrigger or EventTrigger;

Try / catch

try { style.Seal(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("trigger")) { log.Error("Unsupported trigger in style", ex); }

Prevention

When it happens

Trigger: Adding an unsupported TriggerBase subclass to Style.Triggers before Seal — e.g. a custom trigger type, or a template-only trigger type instantiated in code and added to a Style.

Common situations: Custom TriggerBase subclasses written by developers expecting style support; library migration where a template-specific trigger is placed in a style; code that generically adds all triggers from a list without filtering by type.

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

Appendix: source

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

                                StyleHelper.AddPropertyTriggerWithAction(trigger, triggerCondition.Property, ref this.PropertyTriggersWithActions);
                            }
                        }
                        else if (trigger is DataTrigger)
                        {
                            StyleHelper.AddDataTriggerWithAction(trigger, ((DataTrigger)trigger).Binding, ref this.DataTriggersWithActions);
                        }
                        else if (trigger is MultiDataTrigger multiDataTrigger)
                        {
                            for (int k = 0; k < multiDataTrigger.Conditions.Count; k++)
                            {
                                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,

View on GitHub (pinned to 81131a70a4)