dotnet/wpf · error · InvalidOperationException
SR.Format(SR.NoPresentationContextForGivenElement…
Error message
SR.Format(SR.NoPresentationContextForGivenElement, annotatedElement)
What it means
AnnotationComponentManager.AddComponent requires the annotated element to have an AdornerPresentationContext (obtained from its AdornerLayer) before an attached annotation's component can be added. When the element carries no presentation context — meaning it is not in a visual tree with a supported adorner layer — an InvalidOperationException naming the element is thrown.
Solutions
- Ensure the annotated element is fully loaded (handle Loaded event) and inside a DocumentViewerBase or a visual tree providing an AdornerLayer before attaching annotations.
- Check AnnotationComponentManager/AdornerPresentationContext presence for the element before calling the API.
- Defer annotation application until after layout; retry on Loaded if the element was mid-unload.
- For custom hosting, add an AdornerDecorator so an adorner layer exists for the element.
Example fix
// before service.EnableAnnotations(); // element not loaded yet -> throws on attach // after element.Loaded += (s, e) => service.EnableAnnotations(); // attach after element is in visual tree
Defensive patterns
Strategy: validation
Validate before calling
bool hasContext = element != null && element.IsLoaded &&
AdornerLayer.GetAdornerLayer(element as Visual) != null;
if (hasContext) service.AddAttachedAnnotation(attachedAnnotation); Type guard
bool CanAttach(UIElement el) => el.IsLoaded && VisualTreeHelper.GetParent(el) != null && AdornerLayer.GetAdornerLayer(el) != null;
Try / catch
try { service.AddAttachedAnnotation(attachedAnnotation); }
catch (InvalidOperationException) { /* element lacks presentation context; defer to Loaded */ } Prevention
- Attach annotations only after the element is loaded into a viewer/adorner-layer tree
- Use the Loaded event as the attach trigger
- For custom hosts, ensure an AdornerDecorator exists
- Re-apply annotations after viewer re-templating or tree rebuilds
When it happens
Trigger: Calling AddAttachedAnnotation or ModifyAttachedAnnotation (via AnnotationService) for an element whose PresentationContext lookup returned null — e.g. the element is not loaded in a visual tree, or is hosted without an AdornerLayer/DocumentViewerBase.
Common situations: Attaching annotations to a FlowDocumentPageViewer/FlowDocumentReader content before it is loaded; annotating elements inside containers without an adorner layer; calls racing element unload (element removed from tree while annotations are applied); applying annotations after a viewer control was re-templated so the adorner layer is missing.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- ' ' is not a Visual or Visual3D.
- anchorLocator.Parts
- annotation component
- InvalidEnumArgumentException("action", (int)action…
- InvalidEnumArgumentException("action", (int)action…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/ab1eab2ac2b891cb.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Component/AnnotationComponentManager.cs:177
Debug.Assert(annotatedElement != null, "the annotatedElement should inherit from UIElement");
// if annotation component is already in presentation context, nothing else to do
if (component.PresentationContext != null) return;
// otherwise host in the appropriate adorner layer
AdornerLayer layer = AdornerLayer.GetAdornerLayer(annotatedElement); // note, GetAdornerLayer requires UIElement
if (layer == null)
{
if (PresentationSource.FromVisual(annotatedElement) == null)
{
// The annotated element is no longer part of the application tree.
// This probably means we are out of sync - trying to add an annotation
// for an element that has already gone away. Bug # 1580288 tracks
// the need to figure this out.
return;
}
throw new InvalidOperationException(SR.Format(SR.NoPresentationContextForGivenElement, annotatedElement));
}
// add to the attachedAnnotations
this.AddToAttachedAnnotations(attachedAnnotation, component);
// let the annotation component know about the attached annotation
// call add before adding to adorner layer so the component can be initialized
component.AddAttachedAnnotation(attachedAnnotation); // this might cause recursion in modify if annotation component adds to annotation
AdornerPresentationContext.HostComponent(layer, component, annotatedElement, reorder);
}
/// <summary>
/// Service indicates attached annotation has changed.
/// For now, take all annotation components maped from old attached annotation and map from new.
/// Then iterate through annotation components to let them know.
/// Note, this needs to change later. If modify is radical, existing component might not want it anymore,
/// and new one might need to be found... View on GitHub (pinned to 81131a70a4)