dotnet/wpf · error · NotSupportedException
SR.StrokeCollectionIsReadOnly
Error message
SR.StrokeCollectionIsReadOnly
What it means
ReadOnlyStrokeCollection overrides OnStrokesChanged to throw NotSupportedException, because the collection is immutable. Any API that would add, remove, clip, or erase strokes on a read-only collection is rejected. Read-only collections are typically used for presentation of ink that cannot be modified.
Solutions
- Check strokes.IsReadOnly before mutating and take a writable copy first: new StrokeCollection(strokes)
- Use the original, writable InkCanvas.Strokes collection instead of the read-only snapshot
- Avoid calling mutating APIs like Clip/Erase on read-only collections; perform hit-testing only
Example fix
// before readOnlyStrokes.Add(newStroke); // NotSupportedException // after var writable = new StrokeCollection(readOnlyStrokes); writable.Add(newStroke);
Defensive patterns
Strategy: validation
Validate before calling
if (strokes.IsReadOnly) strokes = new StrokeCollection(strokes);
Type guard
bool IsWritable(StrokeCollection sc) => sc != null && !sc.IsReadOnly;
Prevention
- Check IsReadOnly before any Add/Remove/Clip/Erase call
- Copy read-only collections into a new StrokeCollection when mutation is needed
- Keep references to the original writable InkCanvas.Strokes instead of snapshots
When it happens
Trigger: Calling StrokeCollection mutating members (Add, Remove, Insert, Clip, Erase, Clear, indexer set) on a StrokeCollection obtained from a read-only source such as ReadOnlyStrokeCollection returned by certain InkCanvas/Ink APIs; the mutation raises OnStrokesChanged which throws.
Common situations: Attempting ink.Erase(...) or strokes.Add(...) on a collection fetched from an InkCanvas in read-only mode, or after wrapping strokes in AsReadOnly; often a surprise because the method exists but the collection is immutable.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- NotSupportedException
- NotSupportedException
- SR.General_ObjectIsReadOnly
- SR.SetLengthNotSupported
- Stream does not support Write
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a2fed18d279ca00c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/StrokeCollection.cs:858
/// </summary>
internal class ReadOnlyStrokeCollection : StrokeCollection, ICollection<Stroke>, IList
{
internal ReadOnlyStrokeCollection(StrokeCollection strokeCollection)
{
if ( strokeCollection != null )
{
( (List<Stroke>)this.Items ).AddRange(strokeCollection);
}
}
/// <summary>
/// Change is not allowed. We would override SetItem, InsertItem etc but
/// they need to be sealed on StrokeCollection to prevent dupes from being added
/// </summary>
/// <param name="e"></param>
protected override void OnStrokesChanged(StrokeCollectionChangedEventArgs e)
{
throw new NotSupportedException(SR.StrokeCollectionIsReadOnly);
}
/// <summary>
/// IsReadOnly
/// </summary>
bool IList.IsReadOnly
{
get { return true; }
}
/// <summary>
/// IsReadOnly
/// </summary>
bool ICollection<Stroke>.IsReadOnly
{
get { return true; }
}
}View on GitHub (pinned to 81131a70a4)