dotnet/wpf · error · ArgumentException

SR.InvalidSelectionPages

Error message

SR.InvalidSelectionPages

What it means

GetSpannedAnnotations resolves which pages the start and end of the selection fall on. If either TextPointer maps to page -1 (pagination failed or the pointer has no page), the selection cannot be anchored and ArgumentException is thrown.

Solutions

  1. Wait until pagination/layout is complete (IsPageCountValid / LayoutUpdated) before calling GetSpannedAnnotations.
  2. Build selections from TextPointers obtained from rendered content in the viewer rather than from an arbitrary TextContainer.
  3. Catch ArgumentException and defer or retry the call after layout.
  4. Ensure the viewer is loaded and visible so TextPointer pages can be resolved.

Example fix

// before
var annots = AnnotationHelper.GetSpannedAnnotations(service, viewer);
// after
if (viewer.Document is FlowDocument fd && fd.IsPageCountValid)
    var annots = AnnotationHelper.GetSpannedAnnotations(service, viewer);
Defensive patterns

Strategy: try-catch

Validate before calling

bool SelectionHasPages(FlowDocumentScrollViewer v) { var sel = ...; return TextSelectionHelper.GetPointerPage(sel.Start, out var p0) && p0 >= 0; } // resolve pages before calling

Try / catch

try { var annots = AnnotationHelper.GetSpannedAnnotations(service, viewer); } catch (ArgumentException ex) { log.Warn("Selection not paginated yet, retrying after layout: " + ex.Message); viewer.LayoutUpdated += Once(GetSpannedAnnotations); }

Prevention

When it happens

Trigger: Calling AnnotationHelper.GetSpannedAnnotations (or attachedAnnotations/spannedAnnots helpers) with a selection whose start or end TextPointer is not associated with a paginated page — typically a programmatically built selection inside a viewer where pagination has not completed.

Common situations: Querying spanned annotations immediately after changing document content or page size before layout/pagination finished; selections over content in an unloaded or collapsed DocumentViewer page.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/0d35123ca227dfe4. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Annotations/AnnotationHelper.cs:597

            }

            bool allPagesVisible = true;

            ITextSelection selection = GetTextSelection((FrameworkElement)service.Root);
            Invariant.Assert(selection != null, "TextSelection is null");
            int selStartPage = 0, selEndPage = 0;

            if(viewer != null)
            {
                //if this is a DocumentViewerBase check the selection pages
                TextSelectionHelper.GetPointerPage(selection.Start, out selStartPage);
                TextSelectionHelper.GetPointerPage(selection.End, out selEndPage);

                // If either page cannot be found, the selection we are trying to anchor to
                // is invalid.  This can happen if the selection was created programmatically
                // for TextPointers that don't have pages because pagination failed.
                if (selStartPage == -1 || selEndPage == -1)
                    throw new ArgumentException(SR.InvalidSelectionPages);

                allPagesVisible = AreAllPagesVisible(viewer, selStartPage, selEndPage);
            }

            IList<IAttachedAnnotation> attachedAnnotations = null;

            if (allPagesVisible)
            {
                // If viewer is not a DocumentViewerBase or the selection has
                // no parts on non-visible pages, just use the attached annotations
                attachedAnnotations = service.GetAttachedAnnotations();
            }
            else
            {
                // Use the method specific to the kind of content we are displaying
                if (isFlow)
                {
                    attachedAnnotations = GetSpannedAnnotationsForFlow(service, selection);

View on GitHub (pinned to 81131a70a4)