dotnet/wpf · error · ArgumentOutOfRangeException

SR.InvalidMinMaxForButton

Error message

SR.InvalidMinMaxForButton

What it means

StylusPoint.SetPropertyValue throws ArgumentOutOfRangeException when setting a button property (stylusPointProperty.IsButton is true) to a value other than 0 or 1. Button data is packed into a single int where each button occupies one bit, so only 0 (up) and 1 (down) are valid.

Solutions

  1. Pass only 0 or 1 as the value for button properties; unpack multi-button bitmasks and set each button separately.
  2. Coerce with Math.Clamp(value, 0, 1) or bool conversion ((int)(rawState != 0)) before calling.
  3. Catch ArgumentOutOfRangeException when processing untrusted input values.

Example fix

// before
point.SetPropertyValue(tipButton, buttonBitmask);
// after
bool isPressed = (buttonBitmask & 0x1) != 0;
point.SetPropertyValue(tipButton, isPressed ? 1 : 0);
Defensive patterns

Strategy: validation

Validate before calling

if (value >= 0 && value <= 1)
{
    point.SetPropertyValue(buttonProp, value);
}

Type guard

static bool IsValidButtonValue(int v) => v == 0 || v == 1;

Try / catch

try { point.SetPropertyValue(buttonProp, value); }
catch (ArgumentOutOfRangeException) { /* unpack bitmask properly */ }

Prevention

When it happens

Trigger: Calling point.SetPropertyValue(barrelButtonProperty, 2) or any value < 0 or > 1 on a property where IsButton is true.

Common situations: Passing raw button state as an integer count or bitmask (e.g. 3 meaning two buttons pressed) instead of setting each button property individually to 0 or 1.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusPoint.cs:381

                    _pressureFactor = 0.0f;
                }
                else
                {
                    _pressureFactor = (float)(Convert.ToSingle(min + value) / Convert.ToSingle(max));
                }
            }
            else
            {
                int propertyIndex = this.Description.GetPropertyIndex(stylusPointProperty.Id);
                if (-1 == propertyIndex)
                {
                    throw new ArgumentException(SR.InvalidStylusPointProperty, "propertyId");
                }
                if (stylusPointProperty.IsButton)
                {
                    if (value < 0 || value > 1)
                    {
                        throw new ArgumentOutOfRangeException(nameof(value), SR.InvalidMinMaxForButton);
                    }

                    if (copyBeforeWrite)
                    {
                        CopyAdditionalData();
                    }

                    //
                    // we get button data from a single int in the array
                    //
                    int buttonData = _additionalValues[_additionalValues.Length - 1];
                    int buttonBitPosition = this.Description.GetButtonBitPosition(stylusPointProperty);
                    int bit = 1 << buttonBitPosition;
                    if (value == 0)
                    {
                        //turn the bit off
                        buttonData &= ~bit;
                    }

View on GitHub (pinned to 81131a70a4)