dotnet/wpf · error · ArgumentException
SR.CannotBothBeNull (formatted with 'added', 'removed')
Error message
SR.CannotBothBeNull (formatted with 'added', 'removed')
What it means
The StrokeCollectionChangedEventArgs constructor requires at least one of the added/removed collections to be non-null; both being null leaves the event without any meaningful payload. This ArgumentException is thrown when constructing the event args with two nulls.
Solutions
- Pass at least one non-null StrokeCollection (use an empty StrokeCollection to indicate no changes)
- Guard before constructing: if both sources are null, skip raising the event
Example fix
// before new StrokeCollectionChangedEventArgs(null, null); // after new StrokeCollectionChangedEventArgs(added ?? new StrokeCollection(), removed ?? new StrokeCollection());
Defensive patterns
Strategy: validation
Validate before calling
if (added == null && removed == null) return; // skip raising event
Type guard
static bool IsValidStrokeChangeArgs(StrokeCollection a, StrokeCollection r) => a != null || r != null;
Try / catch
try { var e = new StrokeCollectionChangedEventArgs(added, removed); OnChanged(e); } catch (ArgumentException) { /* both null: no change to report */ } Prevention
- Pass empty StrokeCollection instances instead of null for 'no change' sides
- Never construct event args manually with all-null parameters
- Validate event payload before raising
When it happens
Trigger: Subclassing or raising a StrokeCollectionChanged event manually with new StrokeCollectionChangedEventArgs(null, null).
Common situations: Custom ink hosts forwarding stroke changes; test harnesses constructing event args with uninitialized collections.
Related errors
- SR.CannotBothBeNull (formatted with 'newValue'…
- ArgumentOutOfRangeException(nameof(oldProperty))
- ExtendedProperty is already part of the…
- GUID cannot be empty.
- InvalidMatrixContainsInfinity
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/505175b2f1ff986f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/Events.cs:37
public class StrokeCollectionChangedEventArgs : EventArgs
{
private StrokeCollection.ReadOnlyStrokeCollection _added;
private StrokeCollection.ReadOnlyStrokeCollection _removed;
private int _index = -1;
/// <summary>Constructor</summary>
internal StrokeCollectionChangedEventArgs(StrokeCollection added, StrokeCollection removed, int index) :
this(added, removed)
{
_index = index;
}
/// <summary>Constructor</summary>
public StrokeCollectionChangedEventArgs(StrokeCollection added, StrokeCollection removed)
{
if ( added == null && removed == null )
{
throw new ArgumentException(SR.Format(SR.CannotBothBeNull, "added", "removed"));
}
_added = ( added == null ) ? null : new StrokeCollection.ReadOnlyStrokeCollection(added);
_removed = ( removed == null ) ? null : new StrokeCollection.ReadOnlyStrokeCollection(removed);
}
/// <summary>Set of strokes that where added, result may be an empty collection</summary>
public StrokeCollection Added
{
get
{
if ( _added == null )
{
_added = new StrokeCollection.ReadOnlyStrokeCollection(new StrokeCollection());
}
return _added;
}
}
View on GitHub (pinned to 81131a70a4)