dotnet/wpf · error · NotSupportedException

SR.ReadOnlyInputGesturesCollection

Error message

SR.ReadOnlyInputGesturesCollection

What it means

InputGestureCollection can be frozen/read-only (e.g. the default gestures of a RoutedCommand). Attempting IList.Insert on a read-only instance throws NotSupportedException with SR.ReadOnlyInputGesturesCollection.

Solutions

  1. Create your own InputGestureCollection and assign via CommandBinding or custom command
  2. Derive a custom RoutedCommand with your own modifiable InputGestures
  3. Check IsReadOnly before mutating

Example fix

// before
ApplicationCommands.Copy.InputGestures.Insert(0, new KeyGesture(Key.C, ModifierKeys.Control)); // throws
// after
var cmd = new RoutedCommand();
cmd.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Control));
Defensive patterns

Strategy: validation

Validate before calling

if (!cmd.InputGestures.IsReadOnly)
    cmd.InputGestures.Insert(0, gesture);
else
    cmd = new RoutedCommand(name, ownerType, new InputGestureCollection { gesture });

Try / catch

try { gestures.Insert(i, g); }
catch (NotSupportedException) { /* collection is frozen; create own command */ }

Prevention

When it happens

Trigger: Calling the explicit IList.Insert on a collection whose IsReadOnly is true, typically a RoutedCommand's InputGestures collection.

Common situations: Trying to add a gesture directly to an application-level RoutedCommand (e.g. ApplicationCommands.Copy.InputGestures.Insert/Add), which is shared and read-only.

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/117efe54347c47df. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/InputGestureCollection.cs:99

        /// IndexOf
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        int IList.IndexOf(object value)
        {
            InputGesture inputGesture = value as InputGesture;
            return ((inputGesture != null) ? this.IndexOf(inputGesture) : -1) ;
        }

        /// <summary>
        ///  Insert
        /// </summary>
        /// <param name="index">index at which to insert the item</param>
        /// <param name="value">item value to insert</param>
        void IList.Insert(int index, object value)
        {
            if (IsReadOnly)
                 throw new NotSupportedException(SR.ReadOnlyInputGesturesCollection);    

            this.Insert(index, value as InputGesture);
        }

        /// <summary>
        /// Add
        /// </summary>
        /// <param name="inputGesture"></param>
        int IList.Add(object inputGesture) 
        {
            if (IsReadOnly)
                throw new NotSupportedException(SR.ReadOnlyInputGesturesCollection);
            
            return this.Add(inputGesture as InputGesture);
        }

        /// <summary>
        /// Remove

View on GitHub (pinned to 81131a70a4)