dotnet/wpf · error · System.Windows.Automation.ElementNotEnabledException

ElementNotEnabledException

Error message

ElementNotEnabledException

What it means

The UIA Toggle provider for a ListView item checkbox throws ElementNotEnabledException when the checkbox HWND is disabled, per the UIA TogglePattern contract that Toggle is not permitted on disabled elements. The provider checks SafeNativeMethods.IsWindowEnabled(_hwnd) before simulating a click at the checkbox center. It reflects the Win32 state of the underlying list-view item, not a .NET object state.

Solutions

  1. Check the element's IsEnabled property (or IsWindowEnabled on the HWND) before calling Toggle and skip/retry when false
  2. Wait for the app to re-enable the control (poll for enabled state or wait for the modal/busy state to end) before toggling
  3. Fix the application so it does not leave the ListView disabled after the operation completes
  4. Catch ElementNotEnabledException in the automation client and treat it as 'control currently unavailable'

Example fix

// before
((TogglePattern)checkBox.GetCurrentPattern(TogglePattern.Pattern)).Toggle();

// after
if (checkBox.Current.IsEnabled)
{
    ((TogglePattern)checkBox.GetCurrentPattern(TogglePattern.Pattern)).Toggle();
}
else
{
    // wait/retry until the checkbox is enabled
}
Defensive patterns

Strategy: validation

Validate before calling

// C#: check before toggling
AutomationElement checkBox = /* ... */;
if (!checkBox.Current.IsEnabled)
    throw new SkipRetryException("Checkbox is disabled; wait for the app to enable it");
((TogglePattern)checkBox.GetCurrentPattern(TogglePattern.Pattern)).Toggle();

Type guard

bool IsTogglable(AutomationElement el) =>
    el.Current.IsEnabled && el.TryGetCurrentPattern(TogglePattern.Pattern, out _);

Try / catch

try
{
    ((TogglePattern)el.GetCurrentPattern(TogglePattern.Pattern)).Toggle();
}
catch (ElementNotEnabledException)
{
    // element disabled; queue/retry after the UI is re-enabled
}

Prevention

When it happens

Trigger: Calling TogglePattern.Toggle() on a list-view item checkbox whose owning HWND has WS_DISABLED set (IsWindowEnabled returns false). This happens when the ListView control or the item is programmatically disabled, or when a parent window/dialog is disabled (e.g. modal state), since IsWindowEnabled accounts for parent disabling.

Common situations: UI automation scripts or tests driving a checkbox inside a list view while the dialog is disabled during a long operation or modal wait; app code disabling the ListView before the automation client clicks; disabled parent window making the child report disabled even though the item itself is fine.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsListViewItemCheckBox.cs:241

                        return ToggleState.On;
                    }

                case ListViewItem.CheckState.Unchecked :
                    {
                        return ToggleState.Off;
                    }
            }

            // developer defined custom values which cannot be interpret outside of the app's scope
            return ToggleState.Indeterminate;
        }
        
        private void Toggle()
        {
            // Make sure that the control is enabled
            if (!SafeNativeMethods.IsWindowEnabled(_hwnd))
            {
                throw new ElementNotEnabledException();
            }

            Misc.SetFocus(_hwnd);

            NativeMethods.Win32Rect rc = ListViewCheckBoxRect(_hwnd, _listviewItem);
            NativeMethods.Win32Point pt = new NativeMethods.Win32Point((rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2);

            if (Misc.MapWindowPoints(IntPtr.Zero, _hwnd, ref pt, 1))
            {
                // "click" on the checkbox
                Misc.ProxySendMessage(_hwnd, NativeMethods.WM_LBUTTONDOWN, (IntPtr)NativeMethods.MK_LBUTTON, NativeMethods.Util.MAKELPARAM(pt.x, pt.y));
                Misc.ProxySendMessage(_hwnd, NativeMethods.WM_LBUTTONUP, IntPtr.Zero, NativeMethods.Util.MAKELPARAM(pt.x, pt.y));
            }
        }

        #endregion Private Methods
        
        //------------------------------------------------------

View on GitHub (pinned to 81131a70a4)