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
- Validate before use: if (!Enum.IsDefined(typeof(FocusNavigationDirection), direction)) reject/default it.
- Replace raw casts with an explicit, defaulted switch mapping ints to valid directions.
- Persist the direction as its name string instead of a numeric value.
- 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
- Never cast raw ints to FocusNavigationDirection without Enum.IsDefined.
- Persist direction values as names, not numbers.
- Constrain UI/config inputs to the defined direction set with a whitelist.
- Handle diagonals/unsupported directions explicitly before calling navigation APIs.
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
- Animation_UnrecognizedHandoffBehavior
- args
- ArgumentOutOfRangeException(authentication)
- ArgumentOutOfRangeException(authenticationType)
- ArgumentOutOfRangeException(userActivationMode)
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)