dotnet/wpf · error · ArgumentException
SR.InvalidStylusPointCollectionZeroCount
Error message
SR.InvalidStylusPointCollectionZeroCount
What it means
The internal Stroke constructor requires a StylusPointCollection with at least one point. An empty stroke has no geometry, bounds, or drawable path, so WPF rejects empty point collections at construction rather than creating a degenerate Stroke. ArgumentException is thrown naming the stylusPoints parameter.
Solutions
- Guard before constructing: only create a Stroke when stylusPoints.Count > 0
- If empty input is expected, skip stroke creation or use an empty StrokeCollection instead of an empty Stroke
- Populate the StylusPointCollection with at least one StylusPoint before passing it in
Example fix
// before var stroke = new Stroke(stylusPoints); // throws if empty // after if (stylusPoints.Count == 0) return null; var stroke = new Stroke(stylusPoints);
Defensive patterns
Strategy: validation
Validate before calling
if (stylusPoints == null || stylusPoints.Count == 0) return null; // skip stroke creation
Type guard
bool IsValidStrokeSource(StylusPointCollection p) => p != null && p.Count > 0;
Try / catch
try { var stroke = new Stroke(stylusPoints); } catch (ArgumentException ex) when (ex.ParamName == "stylusPoints") { /* handle empty collection */ } Prevention
- Never construct strokes from potentially empty captured point lists
- Represent absence of ink with an empty StrokeCollection, not an empty Stroke
- Assert non-empty point data when deserializing persisted ink
When it happens
Trigger: Calling any public Stroke constructor (Stroke(StylusPointCollection), Stroke(StylusPointCollection, DrawingAttributes)) with a StylusPointCollection whose Count == 0, e.g. new Stroke(new StylusPointCollection()).
Common situations: Building strokes programmatically from captured stylus data that produced no samples; converting persisted ink where a stroke's point list was empty; test fixtures constructing default strokes.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- SR.CollectionNumberOfElementsMustBeGreaterThanZero
- SR.EmptyArray
- SR.EmptyArray
- SR.EmptyArrayNotAllowedAsArgument
- SR.EmptyScToReplaceWith
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/17fbc8b08ef23600.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/Stroke.cs:50
/// <param name="stylusPoints">StylusPointCollection that makes up the stroke</param>
/// <param name="drawingAttributes">drawingAttributes</param>
public Stroke(StylusPointCollection stylusPoints, DrawingAttributes drawingAttributes)
: this(stylusPoints, drawingAttributes, null)
{
}
/// <summary>Create a stroke from a StylusPointCollection</summary>
/// <remarks>
/// </remarks>
/// <param name="stylusPoints">StylusPointCollection that makes up the stroke</param>
/// <param name="drawingAttributes">drawingAttributes</param>
/// <param name="extendedProperties">extendedProperties</param>
internal Stroke(StylusPointCollection stylusPoints, DrawingAttributes drawingAttributes, ExtendedPropertyCollection extendedProperties)
{
ArgumentNullException.ThrowIfNull(stylusPoints);
if (stylusPoints.Count == 0)
{
throw new ArgumentException(SR.InvalidStylusPointCollectionZeroCount, nameof(stylusPoints));
}
ArgumentNullException.ThrowIfNull(drawingAttributes);
_drawingAttributes = drawingAttributes;
_stylusPoints = stylusPoints;
_extendedProperties = extendedProperties;
Initialize();
}
/// <summary>
/// Internal helper to set up listeners, called by ctor and by Clone
/// </summary>
private void Initialize()
{
_drawingAttributes.AttributeChanged += new PropertyDataChangedEventHandler(DrawingAttributes_Changed);
_stylusPoints.Changed += new EventHandler(StylusPoints_Changed);
_stylusPoints.CountGoingToZero += new CancelEventHandler(StylusPoints_CountGoingToZero);View on GitHub (pinned to 81131a70a4)