dotnet/wpf · error · InvalidOperationException
SR.Format(SR.ComponentAlreadyInPresentationContext…
Error message
SR.Format(SR.ComponentAlreadyInPresentationContext, adorner.AnnotationComponent)
What it means
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.
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.
Example fix
// before
var context = new AdornerPresentationContext(adornerLayer, adorner); // throws if reused
// after
if (adorner.AnnotationComponent.PresentationContext != null)
adorner.AnnotationComponent.PresentationContext.RemoveFromHost(adorner.AnnotationComponent);
var context = new AdornerPresentationContext(adornerLayer, adorner); Defensive patterns
Strategy: validation
Validate before calling
if (adorner?.AnnotationComponent == null) throw new ArgumentNullException(nameof(adorner));
if (adorner.AnnotationComponent.PresentationContext != null)
adorner.AnnotationComponent.PresentationContext.RemoveFromHost(adorner.AnnotationComponent); Type guard
bool IsAttachable(AnnotationAdorner a) => a?.AnnotationComponent != null && a.AnnotationComponent.PresentationContext == null;
Try / catch
try { var ctx = new AdornerPresentationContext(layer, adorner); }
catch (InvalidOperationException) { /* component already hosted; reuse or remove first */ } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.AnnotationServiceAlreadyExists
- SR.AnnotationServiceIsAlreadyEnabled
- SR.AnnotationServiceNotEnabled
- SR.Format(SR.ComponentNotInPresentationContext, component)
- SR.InvalidAttachedAnnotation
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/be95efb62f1f9040.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Component/AdornerPresentationContext.cs:46
#region Constructors
/// <summary>
/// Create an initialized instance of an AdornerPresentationContext. Set the presentation context of the
/// component wrapped in the adorner
/// </summary>
/// <param name="adornerLayer">AdornerLayer this presentation context is on, must not be null</param>
/// <param name="adorner">AnnotationAdorner that wraps the annotation component. Will be null in case of creating enclosing context</param>
private AdornerPresentationContext(AdornerLayer adornerLayer, AnnotationAdorner adorner)
{
ArgumentNullException.ThrowIfNull(adornerLayer);
_adornerLayer = adornerLayer;
if (adorner != null)
{
if (adorner.AnnotationComponent == null)
throw new ArgumentNullException("annotation component");
if (adorner.AnnotationComponent.PresentationContext != null)
throw new InvalidOperationException(SR.Format(SR.ComponentAlreadyInPresentationContext, adorner.AnnotationComponent));
_annotationAdorner = adorner;
}
}
#endregion Constructors
#region Static Methods
/// <summary>
/// Host a component in an adorner layer.
/// Wrap the component in an annotation adorner, add that to the adorner layer, create and set presentation context and invalidate to pick up styles.
/// Note, this is called from two places: (1) component manager to host choosen annotation component, and (2) presentation context when component
/// adds additional IAnnotationComponent.
/// </summary>
/// <param name="adornerLayer">Adorner layer the component is hosted in</param>
/// <param name="component">Component that is being hosted</param>
/// <param name="annotatedElement">element being annotated</param>
/// <param name="reorder">if true - put the component on top and calculate its z-order</param>View on GitHub (pinned to 81131a70a4)