stride3d/stride · error · InvalidOperationException

Can only change SelectedItems collection in multiple…

Error message

Can only change SelectedItems collection in multiple selection modes. Use SelectedItem in single select modes.

What it means

The TreeView exposes SelectedItems as an observable collection, but direct mutation is only meaningful in multi-selection modes. In Single selection mode the control keeps SelectedItems in sync with SelectedItem itself; an external add/remove that was not initiated by the control (allowedSelectionChanges false) raises this InvalidOperationException to protect the single-selection invariant.

Solutions

  1. Set treeView.SelectedItem = item instead of modifying SelectedItems when in Single mode.
  2. Switch the TreeView to SelectionMode.Extended if collection mutation is required.
  3. Guard mutation logic on the current SelectionMode before touching SelectedItems.

Example fix

// before
treeView.SelectedItems.Clear();
treeView.SelectedItems.Add(node);
// after
if (treeView.SelectionMode == SelectionMode.Single)
    treeView.SelectedItem = node;
else {
    treeView.SelectedItems.Clear();
    treeView.SelectedItems.Add(node);
}
Defensive patterns

Strategy: validation

Validate before calling

if (treeView.SelectionMode == SelectionMode.Single)
    treeView.SelectedItem = node; // not SelectedItems
else { treeView.SelectedItems.Clear(); treeView.SelectedItems.Add(node); }

Type guard

bool CanMutateSelectedItems(TreeView tv) => tv.SelectionMode != SelectionMode.Single;

Try / catch

try { treeView.SelectedItems.Add(node); }
catch (InvalidOperationException ex) when (ex.Message.Contains("multiple selection modes")) { treeView.SelectedItem = node; }

Prevention

When it happens

Trigger: Calling treeView.SelectedItems.Add(item) / Remove / Clear while SelectionMode is Single, outside of control-internal updates (updatingSelection false and allowedSelectionChanges false).

Common situations: Code shared between single- and multi-select trees that mutates SelectedItems; restoring saved selection state on a Single-mode tree; data-binding code writing into the collection.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/237326d8b31314b3. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Controls/TreeView.cs:632

                        if (item != null)
                            item.IsSelected = false;
                        treeView.SelectedItems.RemoveAt(i);
                    }
                    treeView.updatingSelection = false;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private void OnSelectedItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (updatingSelection)
                return;

            if (SelectionMode == SelectionMode.Single && !allowedSelectionChanges)
                throw new InvalidOperationException("Can only change SelectedItems collection in multiple selection modes. Use SelectedItem in single select modes.");

            updatingSelection = true;

            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    object last = null;
                    foreach (var item in GetTreeViewItemsFor(e.NewItems))
                    {
                        item.IsSelected = true;

                        last = item.DataContext;
                    }

                    SelectedItem = last;
                    break;
                case NotifyCollectionChangedAction.Remove:
                    foreach (var item in GetTreeViewItemsFor(e.OldItems))

View on GitHub (pinned to 96fad776d2)