{"record":{"id":"1f3814daa4c7faca","repo":"dotnet/wpf","slug":"sr-format-sr-componentnotinpresentationcontext-component","errorCode":null,"errorMessage":"SR.Format(SR.ComponentNotInPresentationContext, component)","messagePattern":"SR\\.Format\\(SR\\.ComponentNotInPresentationContext, component\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Component/AdornerPresentationContext.cs","lineNumber":194,"sourceCode":"        /// </summary>\n        /// <param name=\"component\">Component to remove from host</param>\n        /// <param name=\"reorder\">if true - recalculate z-order</param>\n        public override void RemoveFromHost(IAnnotationComponent component, bool reorder)\n        {\n            ArgumentNullException.ThrowIfNull(component);\n\n            if (IsInternalComponent(component))\n            {\n                _annotationAdorner.AnnotationComponent.PresentationContext = null;\n                _adornerLayer.Remove(_annotationAdorner);\n                _annotationAdorner.RemoveChildren();\n                _annotationAdorner = null;\n            }\n            else\n            {// need to find annotation adorner in layer, remove it and do house-keeping\n                AnnotationAdorner foundAdorner = this.FindAnnotationAdorner(component);\n\n                if (foundAdorner == null) throw new InvalidOperationException(SR.Format(SR.ComponentNotInPresentationContext, component));\n\n                _adornerLayer.Remove(foundAdorner);\n                foundAdorner.RemoveChildren();\n\n                // now get rid of reference from presentation context of annotation component to annotation adorner\n                AdornerPresentationContext p = component.PresentationContext as AdornerPresentationContext;\n\n                p?.ResetInternalAnnotationAdorner();\n\n                // finally get rid of reference from annotation component to presentation context\n                component.PresentationContext = null;\n            }\n        }\n\n        /// <summary>\n        /// Invalidate the transform for this adorner. called when adorner inside changed aspects of the transform.\n        /// This might go away if InvalidateMeasure works \n        /// (unclear if Peter means this should work on the adorner or even one down on the annotation component itself)","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Component/AdornerPresentationContext.cs#L176-L212","documentation":"RemoveFromHost throws this InvalidOperationException when asked to remove an annotation component that is not hosted by this AdornerPresentationContext: FindAnnotationAdorner cannot locate a matching AnnotationAdorner in the adorner layer. The framework only removes components it can find, so an unknown component indicates caller bookkeeping is out of sync with the actual visual tree.","triggerScenarios":"Calling AdornerPresentationContext.RemoveFromHost(component) with a component that was never added to this context, was already removed, or was removed via a different AdornerLayer so no matching AnnotationAdorner exists in the layer.","commonSituations":"Double-removal after an unload/unload-then-remove sequence; removing a component against the wrong AdornerLayer (e.g. after the element moved to a different viewer); keeping stale references to components after their DocumentViewer/AdornerDecorator was rebuilt.","solutions":["Verify the component was added to this same context before removing; track added components in a set and only remove members.","Guard the removal: only call RemoveFromHost when component.PresentationContext equals this context.","Catch InvalidOperationException and treat it as already-removed if removal is idempotent by design.","Re-add the component if it was unintentionally removed, then remove it properly in a single teardown path."],"exampleFix":"// before\ncontext.RemoveFromHost(component); // throws if not present\n// after\nif (component.PresentationContext == context)\n    context.RemoveFromHost(component);","handlingStrategy":"validation","validationCode":"bool canRemove = component.PresentationContext is AdornerPresentationContext ctx && ReferenceEquals(ctx, thisContext);\nif (canRemove) thisContext.RemoveFromHost(component);","typeGuard":"bool IsHostedHere(IAnnotationComponent c, AdornerPresentationContext ctx) => ReferenceEquals(c?.PresentationContext, ctx);","tryCatchPattern":"try { context.RemoveFromHost(component); }\ncatch (InvalidOperationException) { /* already removed; treat as idempotent */ }","preventionTips":["Track added components in a set and remove only members","Route all add/remove through one context per layer","Avoid double teardown paths (unload handler + explicit remove)"],"tags":["wpf","annotations","invalid-state","double-removal"],"backgroundTag":"entity-not-found","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}