dotnet/wpf · error · ArgumentOutOfRangeException

SR.Visual_ArgumentOutOfRange

Error message

SR.Visual_ArgumentOutOfRange

What it means

ScrollContentPresenter.GetVisualChild supports at most two children: its TemplateChild (index 0) and the adorner layer (index 1). If TemplateChild is null, even index 0 is invalid, so it throws ArgumentOutOfRangeException with SR.Visual_ArgumentOutOfRange. The presenter's visual tree is missing its expected content part.

Solutions

  1. Delay visual-tree inspection until the element's template is applied (Loaded event or TemplateApplied/OnApplyTemplate).
  2. Check ScrollContentPresenter.TemplateChild != null (or GetChildrenCount > 0) before calling GetVisualChild(0).
  3. If using a custom ScrollViewer template, ensure it contains the required part that becomes the presenter's TemplateChild.

Example fix

// before
var content = VisualTreeHelper.GetChild(scrollContentPresenter, 0); // throws if TemplateChild null
// after
if (VisualTreeHelper.GetChildrenCount(scrollContentPresenter) > 0)
    var content = VisualTreeHelper.GetChild(scrollContentPresenter, 0);
Defensive patterns

Strategy: validation

Validate before calling

if (presenter.TemplateChild == null || VisualTreeHelper.GetChildrenCount(presenter) == 0) return;

Type guard

bool PresenterHasContent(ScrollContentPresenter p) => p.TemplateChild != null;

Try / catch

try { var c = VisualTreeHelper.GetChild(presenter, 0); }
catch (ArgumentOutOfRangeException) { /* template not applied yet */ }

Prevention

When it happens

Trigger: Querying visual children of a ScrollContentPresenter whose template child (the scroll content) hasn't been applied yet — e.g. before the template is instantiated — or requesting an index when the presenter has no content.

Common situations: Automation or hit-testing code walking visuals before template application (pre-Loaded), custom templates for ScrollViewer that omit the required content part, tests inspecting visuals in constructor.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/ScrollContentPresenter.cs:341

            {
                // Four states make sense:
                // 0 Children.  No Content or AdornerLayer.  Valid - do nothing.
                // 2 Children.  Content is first child, AdornerLayer

                // One for the base.TemplateChild and one for the _adornerlayer.
                return (base.TemplateChild == null) ? 0 : 2;
            }
        }

        /// <summary>
        /// Returns the child at the specified index.
        /// </summary>
        protected override Visual GetVisualChild(int index)
        {
            //check if there is a TemplateChild on FrameworkElement
            if (base.TemplateChild == null)
            {
                throw new ArgumentOutOfRangeException(nameof(index), index, SR.Visual_ArgumentOutOfRange);
            }
            else
            {
                switch (index)
                {
                    case 0:
                        return base.TemplateChild;

                    case 1:
                        return _adornerLayer;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(index), index, SR.Visual_ArgumentOutOfRange);
                }
            }
         }

        /// <summary>

View on GitHub (pinned to 81131a70a4)