in src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs [418:550]
internal void KeyDown(IMenuItem? item, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Up:
case Key.Down:
{
if (item?.IsTopLevel == true && item.HasSubMenu)
{
if (!item.IsSubMenuOpen)
{
Open(item, true);
}
else
{
item.MoveSelection(NavigationDirection.First, true);
}
e.Handled = true;
}
else
{
goto default;
}
break;
}
case Key.Left:
{
if (item is { IsSubMenuOpen: true, SelectedItem: null })
{
item.Close();
}
else if (item?.Parent is IMenuItem { IsTopLevel: false, IsSubMenuOpen: true } parent)
{
parent.Close();
parent.Focus();
e.Handled = true;
}
else
{
goto default;
}
break;
}
case Key.Right:
{
if (item != null && !item.IsTopLevel && item.HasSubMenu)
{
Open(item, true);
e.Handled = true;
}
else
{
goto default;
}
break;
}
case Key.Enter:
{
if (item != null)
{
if (!item.HasSubMenu)
{
Click(item);
}
else
{
Open(item, true);
}
e.Handled = true;
}
break;
}
case Key.Escape:
{
if (item?.Parent is IMenuElement parent)
{
parent.Close();
parent.Focus();
}
else
{
Menu!.Close();
}
e.Handled = true;
break;
}
default:
{
var direction = e.Key.ToNavigationDirection();
if (direction?.IsDirectional() == true)
{
if (item == null && _isContextMenu)
{
if (Menu!.MoveSelection(direction.Value, true) == true)
{
e.Handled = true;
}
}
else if (item?.Parent?.MoveSelection(direction.Value, true) == true)
{
// If the parent is an IMenu which successfully moved its selection,
// and the current menu is open then close the current menu and open the
// new menu.
if (item.IsSubMenuOpen &&
item.Parent is IMenu &&
item.Parent.SelectedItem is object &&
item.Parent.SelectedItem != item)
{
item.Close();
Open(item.Parent.SelectedItem, true);
}
e.Handled = true;
}
}
break;
}
}
if (!e.Handled && item?.Parent is IMenuItem parentItem)
{
KeyDown(parentItem, e);
}
}