lepoco/wpfui · error · ArgumentOutOfRangeException
The argument {nameof(index)} must be >= 0 and < the number o
Error message
The argument {nameof(index)} must be >= 0 and < the number of items. What it means
VirtualizingWrapPanel.BringIndexIntoView is the WPF virtualisation contract method called by the framework (and ItemsControl bring-into-view logic) to scroll a given item index into view. It validates that index is within [0, Items.Count) and throws ArgumentOutOfRangeException otherwise. This guards against the panel trying to compute an offset for a row that does not exist.
Source
Thrown at src/Wpf.Ui/Controls/VirtualizingWrapPanel/VirtualizingWrapPanel.cs:495
}
/// <summary>
/// Gets item row index.
/// </summary>
private int GetRowIndex(double location)
{
var calculatedRowIndex = (int)Math.Floor(location / GetHeight(ChildSize));
var maxRowIndex = (int)Math.Ceiling((double)Items.Count / (double)ItemsPerRowCount);
return Math.Max(Math.Min(calculatedRowIndex, maxRowIndex), 0);
}
/// <inheritdoc />
protected override void BringIndexIntoView(int index)
{
if (index < 0 || index >= Items.Count)
{
throw new ArgumentOutOfRangeException(
nameof(index),
$"The argument {nameof(index)} must be >= 0 and < the number of items."
);
}
if (ItemsPerRowCount == 0)
{
throw new InvalidOperationException();
}
var offset = (index / ItemsPerRowCount) * GetHeight(ChildSize);
if (Orientation == Orientation.Horizontal)
{
SetHorizontalOffset(offset);
}
else
{View on GitHub (pinned to ffebacd610)
Solutions
- Bounds-check against the live collection count before calling BringIndexIntoView.
- Re-resolve the index from the item (e.g. via IndexOf) right before scrolling, after any collection reset.
- Avoid scrolling to an index during collection-change notifications; defer to the dispatcher.
Example fix
// before
panel.BringIndexIntoView(selectedIndex);
// after
if (selectedIndex >= 0 && selectedIndex < items.Count)
{
panel.BringIndexIntoView(selectedIndex);
} Defensive patterns
Strategy: validation
Validate before calling
if (index < 0 || index >= items.Count)
{
throw new ArgumentOutOfRangeException(nameof(index));
}
panel.BringIndexIntoView(index); Type guard
static bool IsInViewRange(int index, int count) => index >= 0 && index < count;
Try / catch
try { panel.BringIndexIntoView(index); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "index")
{
_logger.LogDebug(ex, "Stale index {Index} no longer in range.", index);
} Prevention
- Re-resolve the index from the live collection right before scrolling.
- Defer bring-into-view calls until after collection-change processing completes.
- Bounds-check whenever the source may have been filtered or replaced.
When it happens
Trigger: The framework or user code calls BringIndexIntoView with an index that is negative or >= the current Items.Count - e.g. after the source collection changed but before the panel's Items was synchronised, or a stale index retained from a previous larger collection.
Common situations: Collection is replaced/reset between selecting an item and scrolling it into view; bound source filtered down so a previously valid index is now out of range; off-by-one when computing the last index; calling BringIndexIntoView on an empty list.
Related errors
- Unsupported button type: {buttonType}.
- Unable to find the base directory of the application.
- Unable to determine the window source.
- Cannot change DialogHostEx while the dialog is being shown.
- DialogHost was not set
AI-assisted analysis of lepoco/wpfui@ffebacd610 (2026-08-13).
Data as JSON: /api/errors/b4e4b2b5954a5a2c.
Report an issue: GitHub.