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

ElementNotEnabledException

Error message

ElementNotEnabledException

What it means

IRangeValueProvider.SetValue on a list-view scroll bar throws ElementNotEnabledException when the scroll bar's HWND is disabled. The UIA RangeValue contract requires that setting a value on a disabled element fails with this exception. The provider verifies SafeNativeMethods.IsWindowEnabled(_hwnd) before attempting to change the scroll position.

Solutions

  1. Check the element's IsEnabled property before calling SetValue and defer the call until it is true
  2. Re-enable the ListView/window in the application before programmatic scrolling
  3. Retry the SetValue after the disabling condition (modal state, busy operation) is gone
  4. Catch ElementNotEnabledException and treat the scroll operation as currently unavailable

Example fix

// before
((RangeValuePattern)scrollBar.GetCurrentPattern(RangeValuePattern.Pattern)).SetValue(50);

// after
var pattern = (RangeValuePattern)scrollBar.GetCurrentPattern(RangeValuePattern.Pattern);
if (scrollBar.Current.IsEnabled)
{
    pattern.SetValue(50);
}
Defensive patterns

Strategy: validation

Validate before calling

// C#: verify enabled state and range before SetValue
var rv = (RangeValuePattern)scrollBar.GetCurrentPattern(RangeValuePattern.Pattern);
if (!scrollBar.Current.IsEnabled)
    throw new SkipRetryException("Scroll bar is disabled");
if (value < rv.Current.Minimum || value > rv.Current.Maximum)
    throw new ArgumentOutOfRangeException(nameof(value));
rv.SetValue(value);

Type guard

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

Try / catch

try
{
    ((RangeValuePattern)el.GetCurrentPattern(RangeValuePattern.Pattern)).SetValue(val);
}
catch (ElementNotEnabledException)
{
    // retry after the control is re-enabled
catch (ArgumentOutOfRangeException)
{
    // clamp to Minimum/Maximum and retry
}

Prevention

When it happens

Trigger: Calling RangeValuePattern.SetValue() on a WindowsListViewScroll provider whose scroll bar window is disabled (WS_DISABLED, or disabled via a disabled parent window so IsWindowEnabled returns false).

Common situations: See trigger scenarios.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsListViewScroll.cs:49

            internal WindowsListViewScrollBar(IntPtr hwnd, ProxyFragment parent, int item, int sbFlag)
                : base( hwnd, parent, item, sbFlag){}

            #endregion Constructors

            //------------------------------------------------------
            //
            //  Patterns Implementation
            //
            //------------------------------------------------------

            #region RangeValue Pattern

            void IRangeValueProvider.SetValue(double val)
            {
                // Check if the window is disabled
                if (!SafeNativeMethods.IsWindowEnabled (_hwnd))
                {
                    throw new ElementNotEnabledException();
                }

            NativeMethods.ScrollInfo si = new NativeMethods.ScrollInfo
            {
                fMask = NativeMethods.SIF_ALL
            };
            si.cbSize = Marshal.SizeOf (si.GetType ());

                if (!Misc.GetScrollInfo(_hwnd, _sbFlag, ref si))
                {
                    return;
                }

                int pos = (int)val;
                // Throw if val is greater than the maximum or less than the minimum.
                // See remarks for WindowsScrollBar.GetScrollValue(ScrollBarInfo.MaximumPosition)
                // regarding this calculation of the allowed maximum.
                if (pos > si.nMax - si.nPage + (si.nPage > 0 ? 1 : 0))

View on GitHub (pinned to 81131a70a4)