{"record":{"id":"be95efb62f1f9040","repo":"dotnet/wpf","slug":"sr-format-sr-componentalreadyinpresentationcontext-adorner","errorCode":null,"errorMessage":"SR.Format(SR.ComponentAlreadyInPresentationContext, adorner.AnnotationComponent)","messagePattern":"SR\\.Format\\(SR\\.ComponentAlreadyInPresentationContext, adorner\\.AnnotationComponent\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Component/AdornerPresentationContext.cs","lineNumber":46,"sourceCode":"        #region Constructors\n\n        /// <summary>\n        /// Create an initialized instance of an AdornerPresentationContext. Set the presentation context of the \n        /// component wrapped in the adorner\n        /// </summary>\n        /// <param name=\"adornerLayer\">AdornerLayer this presentation context is on, must not be null</param>\n        /// <param name=\"adorner\">AnnotationAdorner that wraps the annotation component.  Will be null in case of creating enclosing context</param>\n        private AdornerPresentationContext(AdornerLayer adornerLayer, AnnotationAdorner adorner)\n        {\n            ArgumentNullException.ThrowIfNull(adornerLayer);\n\n            _adornerLayer = adornerLayer;\n            if (adorner != null)\n            {\n                if (adorner.AnnotationComponent == null)\n                    throw new ArgumentNullException(\"annotation component\");\n                if (adorner.AnnotationComponent.PresentationContext != null)\n                    throw new InvalidOperationException(SR.Format(SR.ComponentAlreadyInPresentationContext, adorner.AnnotationComponent));\n                _annotationAdorner = adorner;\n            }\n        }\n\n        #endregion Constructors\n\n        #region Static Methods\n\n        /// <summary>\n        /// Host a component in an adorner layer.\n        /// Wrap the component in an annotation adorner, add that to the adorner layer, create and set presentation context and invalidate to pick up styles.\n        /// Note, this is called from two places: (1) component manager to host choosen annotation component, and (2) presentation context when component\n        /// adds additional IAnnotationComponent.\n        /// </summary>\n        /// <param name=\"adornerLayer\">Adorner layer the component is hosted in</param>\n        /// <param name=\"component\">Component that is being hosted</param>\n        /// <param name=\"annotatedElement\">element being annotated</param>\n        /// <param name=\"reorder\">if true - put the component on top and calculate its z-order</param>","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Component/AdornerPresentationContext.cs#L28-L64","documentation":"Thrown by the AdornerPresentationContext constructor when the supplied AnnotationAdorner's AnnotationComponent is already attached to another presentation context. The WPF Annotations framework requires each annotation component to live in exactly one presentation context so its visual/adorner bookkeeping stays consistent. Attempting to reuse a component that is still registered elsewhere violates that invariant, so an InvalidOperationException is raised.","triggerScenarios":"Calling the AdornerPresentationContext(adornerLayer, adorner) constructor with an AnnotationAdorner whose AnnotationComponent.PresentationContext is non-null — i.e. the component was previously added to this or another context and not removed.","commonSituations":"Reusing a single AnnotationAdorner/AnnotationComponent instance across multiple annotated elements or multiple AdornerLayer/DocumentViewerHost instances; forgetting to call RemoveFromHost before re-attaching; caching annotation components in application state and re-adding them after a control is re-hosted.","solutions":["Remove the component from its current presentation context (call RemoveFromHost / context.RemoveFromHost) before constructing a new AdornerPresentationContext for it.","Create a fresh AnnotationAdorner/AnnotationComponent instance for each context instead of reusing one.","Check adorner.AnnotationComponent.PresentationContext != null before constructing and branch to an update path instead of re-adding.","If the old host element is gone, ensure the context's cleanup ran so PresentationContext is reset to null."],"exampleFix":"// before\nvar context = new AdornerPresentationContext(adornerLayer, adorner); // throws if reused\n// after\nif (adorner.AnnotationComponent.PresentationContext != null)\n    adorner.AnnotationComponent.PresentationContext.RemoveFromHost(adorner.AnnotationComponent);\nvar context = new AdornerPresentationContext(adornerLayer, adorner);","handlingStrategy":"validation","validationCode":"if (adorner?.AnnotationComponent == null) throw new ArgumentNullException(nameof(adorner));\nif (adorner.AnnotationComponent.PresentationContext != null)\n    adorner.AnnotationComponent.PresentationContext.RemoveFromHost(adorner.AnnotationComponent);","typeGuard":"bool IsAttachable(AnnotationAdorner a) => a?.AnnotationComponent != null && a.AnnotationComponent.PresentationContext == null;","tryCatchPattern":"try { var ctx = new AdornerPresentationContext(layer, adorner); }\ncatch (InvalidOperationException) { /* component already hosted; reuse or remove first */ }","preventionTips":["Treat AnnotationComponent instances as single-context; never share across layers","Always remove from the previous host before re-attaching","Check PresentationContext != null as an attach precondition"],"tags":["wpf","annotations","invalid-state","object-reuse"],"backgroundTag":"invalid-state-transition","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"}