dotnet/wpf · error · ElementNotEnabledException

ElementNotEnabledException

Error message

ElementNotEnabledException

What it means

GridViewColumnHeaderAutomationPeer's IInvokeProvider.Invoke throws ElementNotEnabledException when IsEnabled() is false, i.e. the GridViewColumnHeader (ListView header) is disabled. UIA requires Invoke to fail with this exception rather than silently no-op on disabled elements.

Solutions

  1. Ensure the GridViewColumnHeader and its ancestors are enabled (IsEnabled=true) before invoking.
  2. Check the element's IsEnabled UIA property before calling Invoke.
  3. Catch ElementNotEnabledException in the automation client and defer the click until the control is enabled.
  4. If header interactivity is unwanted, use a header template that is not a disabled button rather than disabling the control.

Example fix

// before
((IInvokeProvider)headerPeer).Invoke();
// after
if (((AutomationPeer)headerPeer).IsEnabled()) ((IInvokeProvider)headerPeer).Invoke();
Defensive patterns

Strategy: validation

Validate before calling

if (!peer.IsEnabled()) throw new SkipTestException("GridViewColumnHeader disabled");

Try / catch

try { ((IInvokeProvider)peer).Invoke(); }
catch (ElementNotEnabledException) { /* wait until enabled, then retry */ }

Prevention

When it happens

Trigger: Invoking the Invoke pattern on a ListView column header while the header or its ListView/ancestor has IsEnabled=false (e.g. during a load state, or header with a disabled template).

Common situations: UI tests clicking ListView column headers (to sort) while the ListView is disabled inside a busy overlay; accessibility tools invoking headers on disabled controls.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/GridViewColumnHeaderAutomationPeer.cs:53

        }

        /// 
        public override object GetPattern(PatternInterface patternInterface)
        {
            if (patternInterface == PatternInterface.Invoke || patternInterface == PatternInterface.Transform)
            {
                return this;
            }
            else
            {
                return base.GetPattern(patternInterface);
            }
        }

        void IInvokeProvider.Invoke()
        {
            if (!IsEnabled())
                throw new ElementNotEnabledException();

            GridViewColumnHeader owner = (GridViewColumnHeader)Owner;
            owner.AutomationClick();
        }

        #region ITransformProvider

        bool ITransformProvider.CanMove { get { return false; } }

        //Note: CanResize can be false if Max/MinWidth,Height has been added on GridViewColumn/ColumnHeader
        bool ITransformProvider.CanResize { get { return true; } }
        bool ITransformProvider.CanRotate { get { return false; } }

        //Note: Don't support Move so far, if users do need this feature to reorder columns, 
        //we can consider to add it later. (One concern is GVCH doesn't support reorder by moving itself)
        void ITransformProvider.Move(double x, double y)
        {
            throw new InvalidOperationException(SR.UIA_OperationCannotBePerformed);

View on GitHub (pinned to 81131a70a4)