{"record":{"id":"bec886af254e9b54","repo":"dotnet/wpf","slug":"sr-eventargisnull-strokecollection","errorCode":null,"errorMessage":"SR.EventArgIsNull","messagePattern":"SR\\.EventArgIsNull","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/StrokeCollection.cs","lineNumber":617,"sourceCode":"            add { _collectionChanged += value; }\n            remove { _collectionChanged -= value; }\n        }\n\n\n        /// <summary>Method called on derived classes whenever a drawing attributes\n        /// change has occurred in the stroke references in the collection</summary>\n        /// <param name=\"e\">The change information for the stroke collection</param>\n        /// <remarks>StrokesChanged will not be called when drawing attributes or\n        /// custom attributes are changed. Changes that trigger StrokesChanged\n        /// include packets or points changing, modified tranforms, and stroke objects\n        /// being added or removed from the collection.\n        /// To ensure that events fire for event listeners, derived classes\n        /// should call this method.</remarks>\n        protected virtual void OnStrokesChanged(StrokeCollectionChangedEventArgs e)\n        {\n            if ( null == e )\n            {\n                throw new ArgumentNullException(nameof(e), SR.EventArgIsNull);\n            }\n\n            //raise our internal event first.  This is used by\n            //our Renderer and IncrementalHitTester since if they can assume\n            //they are the first in the delegate chain, they can be optimized\n            //to not have to handle out of order events caused by 3rd party code\n            //getting called first\n            if ( this.StrokesChangedInternal != null)\n            {\n                this.StrokesChangedInternal(this, e);\n            }\n            if ( this.StrokesChanged != null )\n            {\n                this.StrokesChanged(this, e);\n            }\n            if ( _collectionChanged != null )\n            {\n                //raise CollectionChanged.  We support the following ","sourceCodeStart":599,"sourceCodeEnd":635,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/StrokeCollection.cs#L599-L635","documentation":"StrokeCollection.OnStrokesChanged — the protected virtual event-raiser invoked via RaiseStrokesChanged — throws ArgumentNullException with SR.EventArgIsNull when the StrokeCollectionChangedEventArgs e is null. Derived classes overriding or invoking this method must always supply a real event-args object describing the added/removed strokes.","triggerScenarios":"Calling OnStrokesChanged(null) from derived-class code or RaiseStrokesChanged with an uninitialized args object; constructing change args lazily and passing null when no change data was captured.","commonSituations":"Custom StrokeCollection subclasses that raise change notifications manually; reflection/testing code invoking the protected method with default args; refactoring that left a null args path in place.","solutions":["Always construct StrokeCollectionChangedEventArgs with non-null added/removed StrokeCollection instances before calling OnStrokesChanged.","Guard the call site: if (args != null) OnStrokesChanged(args).","In a subclass override, do not call base.OnStrokesChanged with a null value; rebuild a default args object if data is missing."],"exampleFix":"// before\nOnStrokesChanged(args); // args may be null\n// after\nargs ??= new StrokeCollectionChangedEventArgs(new StrokeCollection(), new StrokeCollection());\nOnStrokesChanged(args);","handlingStrategy":"validation","validationCode":"if (e != null)\n    OnStrokesChanged(e);","typeGuard":"static bool CanRaise(StrokeCollectionChangedEventArgs e) => e != null;","tryCatchPattern":"try { OnStrokesChanged(e); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"e\") { /* supply a real args object */ }","preventionTips":["Always build StrokeCollectionChangedEventArgs with non-null added/removed collections.","Never pass null event args from subclasses; use empty StrokeCollections to signal 'nothing added/removed'.","Coalesce null args with new StrokeCollectionChangedEventArgs(new StrokeCollection(), new StrokeCollection()) at call sites."],"tags":["wpf","ink","null-argument","events"],"backgroundTag":"null-argument","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}