dotnet/wpf · error · InvalidOperationException

Microsoft.Windows.Controls.SR.UIA_OperationCannotBePerformed

Error message

Microsoft.Windows.Controls.SR.UIA_OperationCannotBePerformed

What it means

RibbonSplitButtonAutomationPeer.Toggle() implements IToggleProvider, but toggling is only valid when the RibbonSplitButton's IsCheckable property is true (the button behaves like a checkable toggle). For non-checkable split buttons, Toggle() throws InvalidOperationException (SR.UIA_OperationCannotBePerformed) because TogglePattern is not applicable. Note it first throws ElementNotEnabledException if the control is disabled.

Solutions

  1. Set IsCheckable="True" on the RibbonSplitButton if toggle semantics are desired
  2. For non-checkable split buttons, use Invoke() (or invoke the header button) instead of Toggle()
  3. Check OwningSplitButton.IsCheckable before calling Toggle() in automation code
  4. Catch InvalidOperationException and fall back to Invoke for non-checkable buttons

Example fix

// before
((TogglePattern)splitButtonPeer.GetPattern(TogglePattern.Pattern)).Toggle();
// after
if (splitButton.IsCheckable)
    ((TogglePattern)splitButtonPeer.GetPattern(TogglePattern.Pattern)).Toggle();
else
    ((InvokePattern)splitButtonPeer.GetPattern(InvokePattern.Pattern)).Invoke();
Defensive patterns

Strategy: validation

Validate before calling

bool canToggle = splitButton.IsCheckable && splitButton.IsEnabled;
if (!canToggle) { /* use Invoke or skip */ }

Type guard

bool IsToggleable(RibbonSplitButton b) => b.IsCheckable;

Try / catch

try { togglePattern.Toggle(); }
catch (InvalidOperationException) { /* not checkable: use Invoke instead */ invokePattern?.Invoke(); }

Prevention

When it happens

Trigger: Calling Toggle() on a RibbonSplitButton whose IsCheckable is false; UIA clients that iterate all patterns and call Toggle regardless of IsCheckable.

Common situations: UIA test scripts toggling split buttons; misconfigured RibbonSplitButton in XAML missing IsCheckable="True" when the app intends checkbox-like behavior.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Windows.Controls.Ribbon/Microsoft/Windows/Automation/Peers/RibbonSplitButtonAutomationPeer.cs:74

                // When IsCheckable is false, InvokePattern should be used
                return this;
            }

            return base.GetPattern(patternInterface);
        }

        #endregion

        #region IToggleProvider Members

        void IToggleProvider.Toggle()
        {
            if (!IsEnabled())
                throw new ElementNotEnabledException();

            if (!OwningSplitButton.IsCheckable)
            {
                throw new InvalidOperationException(Microsoft.Windows.Controls.SR.UIA_OperationCannotBePerformed);
            }

            if (OwningSplitButton.HeaderButton != null)
            {
                ToggleButtonAutomationPeer headerButtonAutomationPeer = CreatePeerForElement(OwningSplitButton.HeaderButton) as ToggleButtonAutomationPeer;
                if (headerButtonAutomationPeer != null)
                {
                    ((IToggleProvider)headerButtonAutomationPeer).Toggle();
                }
            }
        }

        ToggleState IToggleProvider.ToggleState
        {
            get
            {
                return OwningSplitButton.IsChecked ? ToggleState.On : ToggleState.Off;
            }

View on GitHub (pinned to 81131a70a4)