dotnet/wpf · error · InvalidEnumArgumentException

direction

Error message

direction

What it means

A KeyboardNavigation helper computes a signed distance metric between rects keyed on FocusNavigationDirection; the switch covers Left/Right/Up/Down and the default arm throws InvalidEnumArgumentException for "direction" because the message is the parameter name. It means an undefined/unsupported FocusNavigationDirection value reached keyboard navigation.

Solutions

  1. Validate before use: if (!Enum.IsDefined(typeof(FocusNavigationDirection), direction)) reject/default it.
  2. Replace raw casts with an explicit, defaulted switch mapping ints to valid directions.
  3. Persist the direction as its name string instead of a numeric value.
  4. If the direction is genuinely unsupported (e.g., a diagonal), choose the nearest supported axis direction or skip navigation.

Example fix

// before
MoveFocus((FocusNavigationDirection)storedInt);

// after
if (Enum.IsDefined(typeof(FocusNavigationDirection), storedInt))
    MoveFocus((FocusNavigationDirection)storedInt);
else
    MoveFocus(FocusNavigationDirection.Down); // safe default
Defensive patterns

Strategy: validation

Validate before calling

if (!Enum.IsDefined(typeof(FocusNavigationDirection), direction))
    direction = FocusNavigationDirection.Down; // or reject the input
navigation.MoveFocus(direction);

Type guard

bool IsDefinedFocusDirection(FocusNavigationDirection d) => Enum.IsDefined(typeof(FocusNavigationDirection), d);

Try / catch

try { MoveFocus(direction); }
catch (System.ComponentModel.InvalidEnumArgumentException ex) when (ex.ParamName == "direction")
{ MoveFocus(FocusNavigationDirection.Down); }

Prevention

When it happens

Trigger: Calling KeyboardNavigation APIs (or internal distance helpers via PredictFocus-like paths) with (FocusNavigationDirection)someInt where the int is not a defined member, or a direction value from another schema/older enum that maps outside the four handled cases.

Common situations: Raw integer casts from persisted settings, interop, or key-mapping tables; deserializing direction from config; binding UI controls to enum values stored as ints that no longer match the enum layout.

Understand the failure class

Background: "invalid argument", "unknown mode", "not supported": invalid enum-like argument errors explained — this error's family across 19 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Input/KeyboardNavigation.cs:2546

        private double GetPerpDistance(Rect sourceRect, Rect targetRect, FocusNavigationDirection direction)
        {
            switch (direction)
            {
                case FocusNavigationDirection.Right :
                    return targetRect.Left - sourceRect.Left;

                case FocusNavigationDirection.Left :
                    return sourceRect.Right - targetRect.Right;

                case FocusNavigationDirection.Up :
                    return sourceRect.Bottom - targetRect.Bottom;

                case FocusNavigationDirection.Down :
                    return targetRect.Top - sourceRect.Top;

                default :
                    throw new System.ComponentModel.InvalidEnumArgumentException("direction", (int)direction, typeof(FocusNavigationDirection));
            }
        }

        // Example when moving down:
        // distance between sourceRect.TopLeft (or Y=vertical baseline)
        // and targetRect.TopLeft
        private double GetDistance(Rect sourceRect, Rect targetRect, FocusNavigationDirection direction)
        {
            Point startPoint;
            Point endPoint;
            switch (direction)
            {
                case FocusNavigationDirection.Right :
                    startPoint = sourceRect.TopLeft;
                    if (_horizontalBaseline != BASELINE_DEFAULT)
                        startPoint.Y = _horizontalBaseline;
                    endPoint = targetRect.TopLeft;
                    break;

View on GitHub (pinned to 81131a70a4)