dotnet/wpf · error · InvalidOperationException

SR.DataGridRow_CannotSelectRowWhenCells

Error message

SR.DataGridRow_CannotSelectRowWhenCells

What it means

DataGridRow's IsSelected property-changed handler throws InvalidOperationException (SR.DataGridRow_CannotSelectRowWhenCells) when IsSelected is set to true on a row whose DataGrid is in DataGridSelectionUnit.Cell (or CellOnly) mode, i.e., when the row IsSelectable is false. In cell-selection mode rows themselves cannot be selected, only cells.

Solutions

  1. Set DataGrid.SelectionUnit to FullRow (or CellOrRowHeader) to allow row selection
  2. Select cells instead: use grid.SelectedCells and select a full row's cells when in cell mode
  3. Guard code paths: check row.IsSelectable before setting IsSelected = true
  4. Clear stale row IsSelected values when switching SelectionUnit at runtime

Example fix

// before
row.IsSelected = true; // grid is in Cell selection mode
// after
if (row.IsSelectable) { row.IsSelected = true; }
else { grid.SelectedCells.Select(new DataGridCellInfo(row.Items[0], firstColumn)); }
Defensive patterns

Strategy: type-guard

Validate before calling

bool canSelectRow(System.Windows.Controls.DataGridRow row) => row.IsSelectable;

Type guard

bool CanSelectRow(DataGridRow row) => row?.IsSelectable == true;

Try / catch

try { row.IsSelected = true; } catch (InvalidOperationException) { /* grid is in Cell selection mode; select cells instead */ }

Prevention

When it happens

Trigger: Setting DataGridRow.IsSelected = true (in code, XAML, or a binding) while the owning DataGrid.SelectionUnit is DataGridSelectionUnit.Cell or CellOnly; programmatically forcing row selection on such a grid.

Common situations: Copying row-selection logic between grids configured with different SelectionUnit values; virtualized/recycled rows re-applying a stale IsSelected value; automation or test code selecting rows regardless of selection mode.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DataGridRow.cs:1054

            get { return (bool)GetValue(IsSelectedProperty); }
            set { SetValue(IsSelectedProperty, value); }
        }

        /// <summary>
        ///     The DependencyProperty for the IsSelected property.
        /// </summary>
        public static readonly DependencyProperty IsSelectedProperty = Selector.IsSelectedProperty.AddOwner(
            typeof(DataGridRow),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal, new PropertyChangedCallback(OnIsSelectedChanged)));

        private static void OnIsSelectedChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            DataGridRow row = (DataGridRow)sender;
            bool isSelected = (bool)e.NewValue;

            if (isSelected && !row.IsSelectable)
            {
                throw new InvalidOperationException(SR.DataGridRow_CannotSelectRowWhenCells);
            }

            DataGrid grid = row.DataGridOwner;
            if (grid != null && row.DataContext != null)
            {
                DataGridAutomationPeer gridPeer = UIElementAutomationPeer.FromElement(grid) as DataGridAutomationPeer;
                if (gridPeer != null)
                {
                    DataGridItemAutomationPeer rowItemPeer = gridPeer.FindOrCreateItemAutomationPeer(row.DataContext) as DataGridItemAutomationPeer;
                    rowItemPeer?.RaisePropertyChangedEvent(
                            System.Windows.Automation.SelectionItemPatternIdentifiers.IsSelectedProperty,
                            (bool)e.OldValue,
                            isSelected);
                }
            }

            // Update the header's IsRowSelected property
            row.NotifyPropertyChanged(row, e, DataGridNotificationTarget.Rows | DataGridNotificationTarget.RowHeaders);

View on GitHub (pinned to 81131a70a4)