dotnet/wpf · error · InvalidOperationException

SR.SetFocusFailed

Error message

SR.SetFocusFailed

What it means

GroupItemAutomationPeer.SetFocusCore tries to move keyboard focus to the GroupItem's Expander toggle button. If Expander.ExpanderToggleButton?.Focus() returns false (focus could not be set), it throws InvalidOperationException(SR.SetFocusFailed). Only used when the NetFx472-compatible accessibility switch is off and the group item has an Expander; otherwise base.SetFocusCore runs.

Solutions

  1. Ensure the Expander's toggle button exists in the template and is focusable/visible before focusing the group item.
  2. Activate the containing window and make the group item visible (bring into view) before calling SetFocus.
  3. Catch InvalidOperationException around SetFocus and retry after expanding/realizing the group.
  4. If 4.7.2 compatibility behavior is required, set the UseNetFx472CompatibleAccessibilityFeatures compatibility switch so base.SetFocusCore is used instead.

Example fix

// before
peer.SetFocus(); // may throw if expander button not focusable
// after
try { peer.SetFocus(); }
catch (InvalidOperationException)
{
    groupItem.BringIntoView();
    peer.SetFocus();
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (groupItem.Expander?.ExpanderToggleButton is not { IsVisible: true, Focusable: true }) bringIntoViewAndRealize();

Type guard

bool Focusable(Expander e) => e?.ExpanderToggleButton is UIElement { Visibility: Visibility.Visible, Focusable: true };

Try / catch

try { peer.SetFocus(); } catch (InvalidOperationException) { groupItem.BringIntoView(); peer.SetFocus(); }

Prevention

When it happens

Trigger: Calling SetFocus() on a GroupItem automation peer where the group item contains an Expander but the Expander's toggle button cannot take focus (not focusable, hidden, window inactive, or Focus() returns false).

Common situations: UIA clients focusing group headers inside grouped ItemsControls (ListBox/CollectionView grouping with expanders) when the expander button is collapsed or the containing window is not active; custom expander templates removing the toggle button or making it non-focusable.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/GroupItemAutomationPeer.cs:314

                        if (cvg.LeafIndexOf(item) >= 0)
                        {
                            AncestorsInvalid = true;
                            ChildrenValid = true;
                        }
                    }
                }
            }
        }


        protected override void SetFocusCore()
        {
            GroupItem owner = (GroupItem)Owner;
            if (!AccessibilitySwitches.UseNetFx472CompatibleAccessibilityFeatures && owner.Expander != null)
            {
                if (owner.Expander.ExpanderToggleButton?.Focus() != true)
                {
                    throw new InvalidOperationException(SR.SetFocusFailed);
                }
            }
            else
            {
                base.SetFocusCore();
            }
        }


        protected override bool IsKeyboardFocusableCore()
        {
            if (_expanderPeer != null)
            {
                return _expanderPeer.IsKeyboardFocusable();
            }
            else
            {
                return base.IsKeyboardFocusableCore();

View on GitHub (pinned to 81131a70a4)