dotnet/wpf · error · ArgumentOutOfRangeException

SR.Visual_ArgumentOutOfRange

Error message

SR.Visual_ArgumentOutOfRange

What it means

CaretElement.GetVisualChild throws ArgumentOutOfRangeException for any index other than 0 — CaretElement exposes exactly one visual child (its _caretElement). This enforces the Visual/VisualChildrenCount contract for the internal text-system caret.

Solutions

  1. Access the child only via VisualTreeHelper.GetChild(caret, 0) / GetChildrenCount, never with hardcoded larger ranges.
  2. Keep index within 0..VisualChildrenCount-1 in any enumeration loop.
  3. In subclasses, override VisualChildrenCount and GetVisualChild consistently.
  4. Restrict visual-tree mutation to the UI thread to avoid count/access races.

Example fix

// before
for (int i = 0; i < 2; i++) Visit(caretElement.GetVisualChild(i));
// after
int n = VisualTreeHelper.GetChildrenCount(caretElement);
for (int i = 0; i < n; i++) Visit(VisualTreeHelper.GetChild(caretElement, i));
Defensive patterns

Strategy: validation

Validate before calling

int n = VisualTreeHelper.GetChildrenCount(caretElement);
if (index >= 0 && index < n) { var child = VisualTreeHelper.GetChild(caretElement, index); }

Type guard

bool HasVisualChild(Visual parent, int index) => index >= 0 && index < VisualTreeHelper.GetChildrenCount(parent);

Try / catch

try { var child = VisualTreeHelper.GetChild(caretElement, i); } catch (ArgumentOutOfRangeException) { break; }

Prevention

When it happens

Trigger: Enumerating CaretElement's visual children with an index >= 1 or negative; overriding VisualChildrenCount in a subclass inconsistently; tooling walking the visual tree beyond the reported count.

Common situations: Custom text-editor controls deriving from or manipulating the caret's visual tree; automation frameworks mis-walking the tree; races where the caret child was swapped between count query and access.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/CaretElement.cs:106

        #region Protected Methods

        /// <summary>
        /// Returns the Visual children count.
        /// </summary>
        protected override int VisualChildrenCount
        {
            get { return (_caretElement == null) ? 0 : 1; }
        }

        /// <summary>
        /// Returns the child at the specified index.
        /// </summary>
        protected override Visual GetVisualChild(int index)
        {
            if (index != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(index), index, SR.Visual_ArgumentOutOfRange);
            }

            return _caretElement;
        }

        // HitTestCore override not to hit testable Caret.
        protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
        {
            // Return null not to hit testable for CaretElement.
            return null;
        }

        // Render override -- we render the selection here.
        protected override void OnRender(DrawingContext drawingContext)
        {
            if (_selectionGeometry != null)
            {
                FrameworkElement owner = GetOwnerElement();

View on GitHub (pinned to 81131a70a4)