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

  1. Set DisplayIndex values within [0, Columns.Count-1] for the current column count
  2. Rely on automatic DisplayIndex assignment (omit explicit values) where possible
  3. Reassign DisplayIndex after all columns are added
  4. 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

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


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)