dotnet/wpf · error · ArgumentOutOfRangeException

SR.Visual_ArgumentOutOfRange

Error message

SR.Visual_ArgumentOutOfRange

What it means

Grid.GetVisualChild(index) throws ArgumentOutOfRangeException (SR.Visual_ArgumentOutOfRange) when index equals the base VisualChildrenCount while the internal _gridLinesRenderer is null. Grid exposes one extra visual child (the gridlines renderer) beyond its content children; asking for that extra index when no renderer exists is out of range.

Solutions

  1. Use VisualTreeHelper.GetChildrenCount(grid) and iterate indices 0..count-1 — the count already accounts for whether the renderer exists.
  2. Only request the extra index after confirming grid.ShowGridLines is true (which instantiates _gridLinesRenderer).
  3. Wrap GetVisualChild in an index check against the grid's VisualChildrenCount.

Example fix

// before
var child = grid.GetVisualChild(grid.VisualChildrenCount); // throws when no gridlines renderer
// after
if (grid.ShowGridLines && index == grid.VisualChildrenCount)
{
    var renderer = grid.GetVisualChild(index); // gridlines renderer
}
else if (index < grid.VisualChildrenCount)
{
    var child = grid.GetVisualChild(index);
}
Defensive patterns

Strategy: type-guard

Validate before calling

int count = VisualTreeHelper.GetChildrenCount(grid); bool valid = index >= 0 && index < count;

Type guard

bool IsValidVisualIndex(Grid g, int i) => i >= 0 && i < VisualTreeHelper.GetChildrenCount(g);

Try / catch

try { var child = grid.GetVisualChild(index); }
catch (ArgumentOutOfRangeException) { /* index past last child; no gridlines renderer present */ }

Prevention

When it happens

Trigger: Calling GetVisualChild(VisualTreeHelper.GetChildrenCount(...)) or GetVisualChild(grid.VisualChildrenCount) on a Grid that has no gridlines renderer (ShowGridLines == false), asking for one past the last real child.

Common situations: Visual-tree walking utilities enumerating children with an off-by-one count; code that assumes the gridlines renderer always exists; tooling/debug visualizers iterating indices 0..Count inclusive.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs:371

        /// <summary>
        ///   Derived class must implement to support Visual children. The method must return
        ///    the child at the specified index. Index must be between 0 and GetVisualChildrenCount-1.
        ///
        ///    By default a Visual does not have any children.
        ///
        ///  Remark:
        ///       During this virtual call it is not valid to modify the Visual tree.
        /// </summary>
        protected override Visual GetVisualChild(int index)
        {
            // because "base.Count + 1" for GridLinesRenderer
            // argument checking done at the base class
            if(index == base.VisualChildrenCount)
            {
                if (_gridLinesRenderer == null)
                {
                    throw new ArgumentOutOfRangeException(nameof(index), index, SR.Visual_ArgumentOutOfRange);
                }
                return _gridLinesRenderer;
            }
            else return base.GetVisualChild(index);
        }

        /// <summary>
        ///  Derived classes override this property to enable the Visual code to enumerate
        ///  the Visual children. Derived classes need to return the number of children
        ///  from this method.
        ///
        ///    By default a Visual does not have any children.
        ///
        ///  Remark: During this virtual method the Visual tree must not be modified.
        /// </summary>
        protected override int VisualChildrenCount
        {
            //since GridLinesRenderer has not been added as a child, so we do not subtract

View on GitHub (pinned to 81131a70a4)