dotnet/wpf · error · ArgumentException
SR.InvalidEmptyStrokeCollection
Error message
SR.InvalidEmptyStrokeCollection
What it means
InkCanvasGestureEventArgs requires the strokes parameter to contain at least one Stroke. An empty StrokeCollection fails the strokes.Count < 1 guard and throws ArgumentException (SR.InvalidEmptyStrokeCollection) because a gesture event with no ink is meaningless for recognition.
Solutions
- Check strokes.Count > 0 before constructing the event args and skip raising the gesture event when empty.
- Erase strokes only after gesture processing completes, not before constructing the args.
- In the Gesture handler, guard with if (e == null || strokeSource.Count == 0) return; when synthesizing args yourself.
Example fix
// before
var args = new InkCanvasGestureEventArgs(collectedStrokes, results);
RaiseEvent(args);
// after
if (collectedStrokes.Count > 0)
{
var args = new InkCanvasGestureEventArgs(collectedStrokes, results);
RaiseEvent(args);
} Defensive patterns
Strategy: validation
Validate before calling
if (strokes == null || strokes.Count < 1)
return; // skip gesture event
var args = new InkCanvasGestureEventArgs(strokes, results); Type guard
bool HasStrokes(StrokeCollection sc) => sc is { Count: > 0 }; Try / catch
try { var args = new InkCanvasGestureEventArgs(strokes, results); RaiseEvent(args); }
catch (ArgumentException ex) when (ex.ParamName == "strokes")
{ /* no ink captured; skip gesture processing */ } Prevention
- Check strokes.Count before constructing gesture event args.
- Erase/remove strokes only after gesture handling completes.
- Never raise the Gesture event programmatically with an empty collection.
When it happens
Trigger: new InkCanvasGestureEventArgs(new StrokeCollection(), results) or passing a collection whose strokes were all removed/erased before the gesture event args were built.
Common situations: Custom gesture handling where the user's stroke was deleted between capture and arg construction; programmatically raising the Gesture event with no ink; replay/test harnesses building args from empty input buffers.
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.InvalidEmptyArray
- SR.EmptyArrayNotAllowedAsArgument
- Can only countersign parts with Digital Signature…
- Duplicates not allowed - signature part already exists.
- ExtendedProperty is already part of the…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/7d5650b239a17073.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Ink/Events.cs:305
/// </summary>
public class InkCanvasGestureEventArgs : RoutedEventArgs
{
private StrokeCollection _strokes;
private List<GestureRecognitionResult> _gestureRecognitionResults;
private bool _cancel;
/// <summary>
/// TBD
/// </summary>
/// <param name="strokes">strokes</param>
/// <param name="gestureRecognitionResults">gestureRecognitionResults</param>
public InkCanvasGestureEventArgs(StrokeCollection strokes, IEnumerable<GestureRecognitionResult> gestureRecognitionResults)
: base(InkCanvas.GestureEvent)
{
ArgumentNullException.ThrowIfNull(strokes);
if (strokes.Count < 1)
{
throw new ArgumentException(SR.InvalidEmptyStrokeCollection, nameof(strokes));
}
ArgumentNullException.ThrowIfNull(gestureRecognitionResults);
List<GestureRecognitionResult> results =
new List<GestureRecognitionResult>(gestureRecognitionResults);
if (results.Count == 0)
{
throw new ArgumentException(SR.InvalidEmptyArray, nameof(gestureRecognitionResults));
}
_strokes = strokes;
_gestureRecognitionResults = results;
}
/// <summary>
/// TBD
/// </summary>
public StrokeCollection Strokes
{
get { return _strokes; }View on GitHub (pinned to 81131a70a4)