{"record":{"id":"35850ca48cf8bacb","repo":"dotnet/wpf","slug":"sr-visualcollection-readonly","errorCode":null,"errorMessage":"SR.VisualCollection_ReadOnly","messagePattern":"SR\\.VisualCollection_ReadOnly","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/VisualCollection.cs","lineNumber":98,"sourceCode":"        internal void VerifyAPIReadWrite()\n        {\n            Debug.Assert(_owner != null);\n            _owner.VerifyAPIReadWrite();\n            VerifyNotReadOnly();\n        }\n\n        internal void VerifyAPIReadWrite(Visual other)\n        {\n            Debug.Assert(_owner != null);\n            _owner.VerifyAPIReadWrite(other);\n            VerifyNotReadOnly();\n        }\n\n        internal void VerifyNotReadOnly()\n        {\n            if (IsReadOnlyInternal)\n            {\n                throw new InvalidOperationException(SR.VisualCollection_ReadOnly); \n            }\n        }\n\n        /// <summary>\n        /// Gets the number of elements in the collection.\n        /// </summary>\n        public int Count\n        {\n            get\n            {\n                VerifyAPIReadOnly();\n\n                return InternalCount;\n            }\n        }\n\n        /// <summary>\n        /// True if the collection allows modifications, otherwise false.","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/VisualCollection.cs#L80-L116","documentation":"Thrown by VisualCollection.VerifyNotReadOnly when a write operation is attempted on a read-only VisualCollection. WPF marks collections read-only in specific internal contexts (e.g. during enumeration or for system-owned collections), and any Add/Insert/Remove/Clear on them is invalid.","triggerScenarios":"Calling Add, Insert, Remove, RemoveAt, or Clear on a VisualCollection whose IsReadOnlyInternal is true — typically a collection obtained from a context where WPF has locked it (e.g. during read-only API paths like CopyTo's VerifyAPIReadOnly usage or system-driven visual management).","commonSituations":"Custom panels/framework code modifying children while WPF holds the collection read-only; writing to a visual's children inside layout or rendering callbacks that obtained the collection in a locked state.","solutions":["Check VisualCollection.IsReadOnly (or IsReadOnlyInternal) before mutating and skip/queue the change.","Perform child modifications outside the read-only window (e.g. after Measure/Arrange completes, via Dispatcher).","Add/remove children via the owning Visual's API on a UI thread at a safe point rather than inside iteration."],"exampleFix":"// before\nvisuals.Add(newChild); // throws when collection is read-only\n// after\nif (!visuals.IsReadOnly)\n{\n    visuals.Add(newChild);\n}","handlingStrategy":"validation","validationCode":"if (visualCollection.IsReadOnly)\n{\n    // queue the mutation for later\n}\nelse\n{\n    visualCollection.Add(child);\n}","typeGuard":"static bool CanMutate(VisualCollection c) => !c.IsReadOnly;","tryCatchPattern":"try { collection.Add(child); }\ncatch (InvalidOperationException) { /* collection locked read-only; defer */ }","preventionTips":["Check IsReadOnly before every mutation of a VisualCollection you don't own.","Don't mutate collections returned from read-only WPF API paths.","Perform child changes on the UI thread outside layout/render callbacks."],"tags":["wpf","visual-collection","read-only","collection"],"backgroundTag":"unsupported-operation","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"}