dotnet/wpf · error · ArgumentOutOfRangeException

SR.DataGrid_DisplayIndexOutOfRange

Error message

SR.DataGrid_DisplayIndexOutOfRange

What it means

DataGrid.ColumnFromDisplayIndex maps a column's DisplayIndex to the corresponding DataGridColumn and throws ArgumentOutOfRangeException(SR.DataGrid_DisplayIndexOutOfRange) when displayIndex is negative or >= Columns.Count. DisplayIndex is a zero-based position within the displayed column order, not the column collection index.

Solutions

  1. Validate 0 <= displayIndex && displayIndex < dataGrid.Columns.Count before calling.
  2. Clamp or recompute stored DisplayIndex values after column count changes when restoring layouts.
  3. Compare against dataGrid.Columns.Count at call time, not a cached count.
  4. Catch ArgumentOutOfRangeException around layout-restore code and skip invalid entries.

Example fix

// before
var col = dataGrid.ColumnFromDisplayIndex(savedIndex); // may throw
// after
if (savedIndex >= 0 && savedIndex < dataGrid.Columns.Count)
    var col = dataGrid.ColumnFromDisplayIndex(savedIndex);
Defensive patterns

Strategy: validation

Validate before calling

bool inRange = displayIndex >= 0 && displayIndex < dataGrid.Columns.Count;

Type guard

static bool IsValidDisplayIndex(DataGrid grid, int displayIndex) => displayIndex >= 0 && displayIndex < grid.Columns.Count;

Try / catch

try
{
    var col = dataGrid.ColumnFromDisplayIndex(displayIndex);
}
catch (ArgumentOutOfRangeException)
{
    // stale/persisted index; recompute from current layout
}

Prevention

When it happens

Trigger: Calling ColumnFromDisplayIndex with a value outside [0, Columns.Count-1] — e.g. saved DisplayIndex from a previous session, a value from user input, or an index computed before columns were added/reordered.

Common situations: Persisting/restoring column layouts where the user removed columns, computing display indexes from another grid's layout, or using the index during column add/remove events when the collection state differs.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DataGrid.cs:383

            }

            // we're not going to retry
            BringColumnIntoViewRetryCountField.ClearValue(this);
            return false;
        }

        #endregion

        #region Display Index

        /// <summary>
        ///     Returns the DataGridColumn with the given DisplayIndex
        /// </summary>
        public DataGridColumn ColumnFromDisplayIndex(int displayIndex)
        {
            if (displayIndex < 0 || displayIndex >= Columns.Count)
            {
                throw new ArgumentOutOfRangeException(nameof(displayIndex), displayIndex, SR.DataGrid_DisplayIndexOutOfRange);
            }

            return InternalColumns.ColumnFromDisplayIndex(displayIndex);
        }

        /// <summary>
        ///     Event that is fired when the DisplayIndex on one of the DataGrid's Columns changes.
        /// </summary>
        public event EventHandler<DataGridColumnEventArgs> ColumnDisplayIndexChanged;

        /// <summary>
        ///     Called when the DisplayIndex of a column is modified.
        /// </summary>
        /// <remarks>
        ///     A column's DisplayIndex may be modified as the result of another column's DisplayIndex changing.  This is because the
        ///     DataGrid enforces that the DisplayIndex of all Columns are unique integers from 0 to Columns.Count -1.
        /// </remarks>
        protected internal virtual void OnColumnDisplayIndexChanged(DataGridColumnEventArgs e)

View on GitHub (pinned to 81131a70a4)