dotnet/wpf · error · System.ArgumentOutOfRangeException

SR.RangeValueMax

Error message

SR.RangeValueMax

What it means

IRangeValueProvider.SetValue on a list-view scroll bar throws ArgumentOutOfRangeException with SR.RangeValueMax when the requested position exceeds the scroll bar's effective maximum. Because of Win32 scroll-bar semantics, the allowed maximum is nMax - nPage + (nPage > 0 ? 1 : 0), not simply nMax. The provider fetches SCROLLINFO (SIF_ALL) and validates pos against this computed maximum before scrolling.

Solutions

  1. Clamp the requested value to the effective maximum: min(val, nMax - nPage + (nPage > 0 ? 1 : 0))
  2. Query the current scroll info (or RangeValue.Maximum) immediately before SetValue, since nPage/nMax change with resizing
  3. Catch ArgumentOutOfRangeException and clamp/retry within the valid range
  4. Use Scroll patterns or SendMessage(WM_HSCROLL/WM_VSCROLL) with SB_BOTTOM/SB_PAGEDOWN instead of absolute positions

Example fix

// before
rangeValue.SetValue(maximum); // Maximum can exceed the scrollable maximum

// after
double effectiveMax = rangeValue.Current.Maximum - rangeValue.Current.LargeChange + 1;
rangeValue.SetValue(Math.Min(value, Math.Max(rangeValue.Current.Minimum, effectiveMax)));
Defensive patterns

Strategy: validation

Validate before calling

// C#: clamp to the effective scrollable maximum before calling SetValue
var rv = (RangeValuePattern)scrollBar.GetCurrentPattern(RangeValuePattern.Pattern);
var info = rv.Current;
// Win32 effective max accounts for page size (LargeChange maps to nPage)
double effectiveMax = info.Maximum - info.LargeChange + 1;
value = Math.Max(info.Minimum, Math.Min(value, Math.Max(info.Minimum, effectiveMax)));
rv.SetValue(value);

Type guard

bool InEffectiveRange(RangeValuePattern.RangeValueInformation info, double v) =>
    v >= info.Minimum && v <= Math.Max(info.Minimum, info.Maximum - info.LargeChange + 1);

Try / catch

try
{
    rv.SetValue(value);
}
catch (ArgumentOutOfRangeException)
{
    var i = rv.Current;
    rv.SetValue(Math.Min(value, Math.Max(i.Minimum, i.Maximum - i.LargeChange + 1)));
}

Prevention

When it happens

Trigger: Calling RangeValuePattern.SetValue(val) on a list-view scroll bar with val greater than si.nMax - si.nPage + (si.nPage > 0 ? 1 : 0), where si comes from GetScrollInfo with SIF_ALL. Failing to account for the nPage adjustment when reading Maximum is the typical cause.

Common situations: Automation scripts computing the max scroll position from the RangeValue.Maximum property or raw nMax and passing values at/above it without the page-size correction; list view resized so nPage changed between reading the range and setting the value.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

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

            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))
                {
                    throw new ArgumentOutOfRangeException("value", val, SR.RangeValueMax);
                }
                else if (pos < si.nMin)
                {
                    throw new ArgumentOutOfRangeException("value", val, SR.RangeValueMin);
                }

                // LVM_SCROLL does not work in mode Report, use SetScrollPos instead
                bool isVerticalScroll = IsScrollBarVertical(_hwnd, _sbFlag);
                if (isVerticalScroll && WindowsListView.InReportView (_hwnd))
                {
                    Misc.SetScrollPos(_hwnd, _sbFlag, pos, true);
                    return;
                }

                // get the "full size" of the list-view
                int size = WindowsListView.ApproximateViewRect (_hwnd);

                // delta between current and user-requested position in pixels

View on GitHub (pinned to 81131a70a4)