Skip to content

ControlAccessibleObject should bridge GetFocused() to UIA IRawElementProviderFragmentRoot.GetFocus() #14412

@trypsynth

Description

@trypsynth

Summary

When building a custom WinForms control with child accessible objects (e.g. a grid where each cell is a CellAccessibleObject : AccessibleObject), overriding GetFocused() on a ControlAccessibleObject subclass correctly exposes the focused child to MSAA clients. However, UIA clients, including NVDA, never see it.

Root cause

IRawElementProviderFragmentRoot.GetFocus() is implemented in AccessibleObject by calling an internal virtual method that returns null by default. ControlAccessibleObject does not override it, so UIA always reports the control itself as focused, regardless of what GetFocused() returns. DataGridView works correctly because it overrides GetFocus() from inside the WinForms assembly:

internal override IRawElementProviderFragment.Interface? GetFocus() => GetFocused();

External code has no equivalent escape hatch. GetFocused() is public and functional, but the UIA path never reaches it. To repro:

  1. Create a custom control with a ControlAccessibleObject subclass
  2. Override GetFocused() to return a child AccessibleObject
  3. Focus the control with NVDA running
  4. Press NVDA+Tab to read the focused element

Actual result: NVDA reports the control, not the child cell.

Expected result: NVDA reports the focused child (the cell accessible object returned by GetFocused())

Proposed fix

Either make GetFocus() protected virtual so external subclasses can override it, or have ControlAccessibleObject implement it as return GetFocused() as IRawElementProviderFragment.Interface; by default, matching what DataGridView already does internally.

Metadata

Metadata

Assignees

Labels

tenet-accessibilityMAS violation, UIA issue; problems with accessibility standardsuntriagedThe team needs to look at this issue in the next triage

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions