dotnet/wpf · error · ArgumentOutOfRangeException

SR.PaginatorNegativePageNumber

Error message

SR.PaginatorNegativePageNumber

What it means

DocumentPaginator.GetPageAsync throws ArgumentOutOfRangeException when the pageNumber parameter is negative. Page numbers are zero-based; a negative value can never identify a valid page, so the async wrapper validates before calling GetPage.

Solutions

  1. Validate pageNumber >= 0 before calling GetPageAsync
  2. Treat -1 as 'no page' sentinel and skip the call
  3. Clamp with Math.Max(0, pageNumber) where a page is guaranteed to exist

Example fix

// before
paginator.GetPageAsync(currentPage - 1, userState);
// after
int pageIndex = currentPage - 1;
if (pageIndex >= 0)
{
    paginator.GetPageAsync(pageIndex, userState);
}
Defensive patterns

Strategy: validation

Validate before calling

if (pageNumber < 0) throw new ArgumentOutOfRangeException(nameof(pageNumber), "Page number must be zero or greater.");

Type guard

bool IsValidPage(int pageNumber) => pageNumber >= 0;

Try / catch

try { await paginator.GetPageAsync(pageNumber, null); }
catch (ArgumentOutOfRangeException) { pageNumber = 0; }

Prevention

When it happens

Trigger: Calling paginator.GetPageAsync(pageNumber, userState) with a negative pageNumber, typically a value computed from an uninitialized variable, an off-by-one subtraction, or data bound from a saved page index of -1 (no page).

Common situations: XPS/FixedDocument printing code that saved -1 as 'no current page' and later passes it to GetPageAsync; index arithmetic like currentPage-1 on page 0; UI bindings without validation.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Documents/DocumentPaginator.cs:77

            GetPageAsync(pageNumber, null);
        }

        /// <summary>
        /// Async version of <see cref="DocumentPaginator.GetPage"/>
        /// </summary>
        /// <param name="pageNumber">Page number.</param>
        /// <param name="userState">Unique identifier for the asynchronous task.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// Throws ArgumentOutOfRangeException if PageNumber is negative.
        /// </exception>
        public virtual void GetPageAsync(int pageNumber, object userState)
        {
            DocumentPage page;

            // Page number cannot be negative.
            if (pageNumber < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(pageNumber), SR.PaginatorNegativePageNumber);
            }

            page = GetPage(pageNumber);
            OnGetPageCompleted(new GetPageCompletedEventArgs(page, pageNumber, null, false, userState));
        }

        /// <summary>
        /// Computes the number of pages of content. IsPageCountValid will be 
        /// True immediately after this is called.
        /// </summary>
        /// <remarks>
        /// If content is modified or PageSize is changed (or any other change 
        /// that causes a repagination) after this method is called, 
        /// IsPageCountValid will likely revert to False.
        /// </remarks>
        public virtual void ComputePageCount()
        {
            // Force pagination of entire content.

View on GitHub (pinned to 81131a70a4)