dotnet/wpf · error · InvalidEnumArgumentException

InvalidEnumArgumentException("key", (int)key, typeof(Key))

Error message

InvalidEnumArgumentException("key", (int)key, typeof(Key))

What it means

The private KeyGesture constructor validates the Key argument with IsDefinedKey and throws InvalidEnumArgumentException for 'key' when the value is not a defined Key enum member. This rejects out-of-range or undefined key codes.

Solutions

  1. Pass only Key enum members accepted by IsDefinedKey (real keys, not None or internal values)
  2. Validate with IsDefinedKey before constructing the gesture
  3. Map interop VK codes to Key via KeyInterop.KeyFromVirtualKey and validate

Example fix

// before
var gesture = new KeyGesture((Key)vkCode, ModifierKeys.Control);
// after
var key = KeyInterop.KeyFromVirtualKey(vkCode);
if (IsDefinedKey(key)) // or wrap in try/catch
{
    var gesture = new KeyGesture(key, ModifierKeys.Control);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!Enum.IsDefined(typeof(Key), key) || key == Key.None) throw new ArgumentOutOfRangeException(nameof(key));

Type guard

static bool IsUsableKey(Key k) => k != Key.None && Enum.IsDefined(typeof(Key), k);

Try / catch

try { var g = new KeyGesture(key, modifiers); } catch (InvalidEnumArgumentException ex) { /* undefined key value */ }

Prevention

When it happens

Trigger: Calling a public KeyGesture constructor with a Key cast from an arbitrary int (e.g. (Key)1000) or a special/deprecated member not accepted by IsDefinedKey.

Common situations: Building gestures from persisted numeric key codes in config or from interop virtual-key values without mapping them to WPF Key values.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/KeyGesture.cs:94

        internal KeyGesture(Key key, ModifierKeys modifiers, bool validateGesture)
            : this(key, modifiers, String.Empty, validateGesture)
        {
        }

        /// <summary>
        /// Private constructor that does the real work.
        /// </summary>
        /// <param name="key">Key</param>
        /// <param name="modifiers">Modifiers</param>
        /// <param name="displayString">display string</param>
        /// <param name="validateGesture">If true, throws an exception if the key and modifier are not valid</param>
        private KeyGesture(Key key, ModifierKeys modifiers, string displayString, bool validateGesture)
        {
            if(!ModifierKeysConverter.IsDefinedModifierKeys(modifiers))
                throw new InvalidEnumArgumentException("modifiers", (int)modifiers, typeof(ModifierKeys));

            if(!IsDefinedKey(key))
                throw new InvalidEnumArgumentException("key", (int)key, typeof(Key));

            ArgumentNullException.ThrowIfNull(displayString);

            if (validateGesture && !IsValid(key, modifiers))
            {
                throw new NotSupportedException(SR.Format(SR.KeyGesture_Invalid, modifiers, key));
            }

            _modifiers = modifiers;
            _key = key;
            _displayString = displayString;
        }
#endregion Constructors

        //------------------------------------------------------
        //
        //  Public Methods
        //

View on GitHub (pinned to 81131a70a4)