dotnet/wpf · error · NotSupportedException

SR.UnexpectedCollectionChangeAction

Error message

SR.UnexpectedCollectionChangeAction

What it means

TreeViewItem's own OnItemsChanged, like TreeView's, throws NotSupportedException for any NotifyCollectionChangedAction it does not explicitly handle (only Add and Move pass through unhandled in the shown default switch). It indicates the child-items source raised a change action the node cannot process.

Solutions

  1. Back child items with ObservableCollection<T>.
  2. Correct the custom collection's RaiseChanged calls to use valid actions.
  3. Raise a Reset notification instead of unsupported fine-grained actions.

Example fix

// before
handler(this, new NotifyCollectionChangedEventArgs((NotifyCollectionChangedAction)99));
// after
handler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
Defensive patterns

Strategy: validation

Validate before calling

if (e.Action is NotifyCollectionChangedAction.Add or NotifyCollectionChangedAction.Move) { /* handled */ }
else { /* rebuild or Reset instead */ }

Try / catch

try { node.Items.Add(item); }
catch (NotSupportedException) { /* child collection raised unsupported action; reset node.ItemsSource */ }

Prevention

When it happens

Trigger: A TreeViewItem's ItemsSource collection raising an unexpected/invalid collection-change action, or a custom child collection emitting non-standard actions.

Common situations: Custom hierarchical collections with hand-written change notification; data layer emitting unusual actions on nested nodes; third-party observable tree collections.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/TreeViewItem.cs:979

                        if (tree != null)
                        {
                            // When Selected item is replaced - remove the selection
                            // Revisit the condition when we support duplicate items in Items collection: if e.OldItems[0] is the same as selected items we will unselect the selected item
                            object selectedItem = tree.SelectedItem;
                            if ((selectedItem != null) && selectedItem.Equals(e.OldItems[0]))
                            {
                                tree.ChangeSelection(selectedItem, tree.SelectedContainer, false);
                            }
                        }
                    }
                    break;

                case NotifyCollectionChangedAction.Add:
                case NotifyCollectionChangedAction.Move:
                    break;

                default:
                    throw new NotSupportedException(SR.Format(SR.UnexpectedCollectionChangeAction, e.Action));
            }
        }

        /// <summary>
        /// Recursively & syncronously expand all the nodes in this subtree.
        /// </summary>
        private static void ExpandRecursive(TreeViewItem item)
        {
            if (item == null)
            {
                return;
            }

            // Expand the current item
            if (!item.IsExpanded)
            {
                item.SetCurrentValueInternal(IsExpandedProperty, BooleanBoxes.TrueBox);
            }

View on GitHub (pinned to 81131a70a4)