dotnet/wpf · error · ArgumentOutOfRangeException
SR.DataGrid_ColumnDisplayIndexOutOfRange
Error message
SR.DataGrid_ColumnDisplayIndexOutOfRange
What it means
DataGridColumnCollection.InitializeDisplayIndexMap throws ArgumentOutOfRangeException with DataGrid_ColumnDisplayIndexOutOfRange when a column being processed has a DisplayIndex >= the number of columns. DisplayIndex must be a valid position within the collection; the check runs while building the display-index map.
Solutions
- Set DisplayIndex values within [0, Columns.Count-1] for the current column count
- Rely on automatic DisplayIndex assignment (omit explicit values) where possible
- Reassign DisplayIndex after all columns are added
- Fix saved/serialized layouts to clamp DisplayIndex to the new column count
Example fix
// before
var col = new DataGridTextColumn { DisplayIndex = 5 };
grid.Columns.Add(col); // grid has 2 columns
// after
var col = new DataGridTextColumn();
grid.Columns.Add(col);
col.DisplayIndex = Math.Min(5, grid.Columns.Count - 1); Defensive patterns
Strategy: validation
Validate before calling
if (displayIndex < 0 || displayIndex >= grid.Columns.Count)
displayIndex = Math.Max(0, grid.Columns.Count - 1); // clamp Try / catch
try { column.DisplayIndex = i; }
catch (ArgumentOutOfRangeException) { column.DisplayIndex = grid.Columns.Count - 1; } Prevention
- Assign DisplayIndex only after all columns are added
- Clamp saved DisplayIndex values when restoring layouts
- Let the DataGrid auto-assign DisplayIndex when order does not matter
When it happens
Trigger: Setting a column's DisplayIndex to a value greater than or equal to Columns.Count (outside first-measure/init); programmatically assigning DisplayIndex before other columns exist; XAML where DisplayIndex exceeds the column count.
Common situations: Assigning DisplayIndex=5 to the only column; restoring saved layouts where columns were removed but saved DisplayIndex values kept; template/default DisplayIndex values conflicting with a reduced column set.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- SR.DataGrid_DisplayIndexOutOfRange
- SR.DataGrid_DuplicateDisplayIndex
- args
- args
- ArgumentOutOfRangeException(authenticationType)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/0b67a01cea12aa1c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DataGridColumnCollection.cs:475
}
private void InitializeDisplayIndexMap(DataGridColumn changingColumn, int oldDisplayIndex, out int resultDisplayIndex)
{
resultDisplayIndex = oldDisplayIndex;
if (_displayIndexMapInitialized)
{
return;
}
_displayIndexMapInitialized = true;
Debug.Assert(DisplayIndexMap.Count == 0, "DisplayIndexMap should be empty until first measure call.");
int columnCount = Count;
Dictionary<int, int> assignedDisplayIndexMap = new Dictionary<int, int>(); // <DisplayIndex, ColumnIndex>
if (changingColumn != null && oldDisplayIndex >= columnCount)
{
throw new ArgumentOutOfRangeException("displayIndex", oldDisplayIndex, SR.Format(SR.DataGrid_ColumnDisplayIndexOutOfRange, changingColumn.Header));
}
// First loop:
// 1. Validate all columns DisplayIndex
// 2. Add columns with DisplayIndex!=default to the assignedDisplayIndexMap
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++)
{
DataGridColumn currentColumn = this[columnIndex];
int currentColumnDisplayIndex = currentColumn.DisplayIndex;
ValidateDisplayIndex(currentColumn, currentColumnDisplayIndex);
if (currentColumn == changingColumn)
{
currentColumnDisplayIndex = oldDisplayIndex;
}
if (currentColumnDisplayIndex >= 0)View on GitHub (pinned to 81131a70a4)