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
- Use VisualTreeHelper.GetChildrenCount(grid) and iterate indices 0..count-1 — the count already accounts for whether the renderer exists.
- Only request the extra index after confirming grid.ShowGridLines is true (which instantiates _gridLinesRenderer).
- 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
- Use VisualTreeHelper.GetChildrenCount as the bound
- Assume gridlines renderer exists only when ShowGridLines is true
- Iterate with 0..count-1, never count itself
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
- Specified index is out of range or child at index is null…
- Specified index is out of range or child at index is null…
- SR.Format(SR.GridCollection_DestArrayInvalidLowerBound…
- SR.GridCollection_DestArrayInvalidLowerBound
- SR.TableCollectionOutOfRange
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 subtractView on GitHub (pinned to 81131a70a4)