dotnet/wpf · error · ArgumentException
SR.InvalidStylusPointDescriptionButtonsMustBeLast
Error message
SR.InvalidStylusPointDescriptionButtonsMustBeLast
What it means
The StylusPointDescription constructor enforces that all button properties are placed last in the collection, after every non-button property. Once a button has been seen in the iteration, any subsequent non-button property triggers this ArgumentException, because the internal layout expects data axes followed by button bits.
Solutions
- Reorder so all non-button StylusPointPropertyInfos come first (after the mandatory X, Y, NormalPressure) and all buttons come last.
- Partition the collection with LINQ: nonButtons.Concat(buttons) before constructing.
- Check each info's IsButton flag; WPF's TipButton/BarrelButton properties have IsButton true, custom axes false.
Example fix
// before
var desc = new StylusPointDescription(new[]{ x, y, pressure, tipButton, tiltX });
// after
var desc = new StylusPointDescription(new[]{ x, y, pressure, tiltX, tipButton }); Defensive patterns
Strategy: validation
Validate before calling
bool buttonsLast = !infos.Skip(3).Select((i, idx) => (i, idx))
.SkipWhile(t => !t.i.IsButton)
.Any(t => !t.i.IsButton); // any non-button after first button is invalid Try / catch
try { var desc = new StylusPointDescription(infos); }
catch (ArgumentException) { var ordered = infos.Take(3).Concat(infos.Skip(3).Where(i => !i.IsButton)).Concat(infos.Skip(3).Where(i => i.IsButton)).ToArray(); desc = new StylusPointDescription(ordered); } Prevention
- Partition properties into axes and buttons, then concatenate axes-then-buttons
- Never sort the collection alphabetically after building it
- Check IsButton when appending new properties
When it happens
Trigger: Calling new StylusPointDescription(infos) where a non-button StylusPointPropertyInfo (IsButton == false) appears after any button property (IsButton == true) in the collection.
Common situations: Appending custom axis properties (e.g. tilt, twist) after button properties when building a description; concatenating a custom-axis list onto a device list that already ended with buttons; re-sorting the collection alphabetically which moves buttons before some axes.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.IncompatibleStylusPointDescriptions
- SR.InvalidIsButtonForId
- SR.InvalidIsButtonForId2
- SR.InvalidStylusPointDescription
- SR.InvalidStylusPointDescriptionDuplicatesFound
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/6e7233d9795de35c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusPointDescription.cs:82
seenIds.Add(StylusPointPropertyIds.NormalPressure);
int buttonCount = 0;
for (int x = RequiredCountOfProperties; x < infos.Count; x++)
{
if (seenIds.Contains(infos[x].Id))
{
throw new ArgumentException(SR.InvalidStylusPointDescriptionDuplicatesFound, nameof(stylusPointPropertyInfos));
}
if (infos[x].IsButton)
{
buttonCount++;
}
else
{
//this is not a button, make sure we haven't seen one before
if (buttonCount > 0)
{
throw new ArgumentException(SR.InvalidStylusPointDescriptionButtonsMustBeLast, nameof(stylusPointPropertyInfos));
}
}
seenIds.Add(infos[x].Id);
}
if (buttonCount > MaximumButtonCount)
{
throw new ArgumentException(SR.InvalidStylusPointDescriptionTooManyButtons, nameof(stylusPointPropertyInfos));
}
_buttonCount = buttonCount;
_stylusPointPropertyInfos = infos.ToArray();
}
/// <summary>
/// StylusPointDescription
/// </summary>
/// <param name="stylusPointPropertyInfos">stylusPointPropertyInfos</param>
/// <param name="originalPressureIndex">originalPressureIndex - does the digitizer really support pressure? If so, the index this was at</param>View on GitHub (pinned to 81131a70a4)