Primary APIs:
TopLevel.FocusManagerFocusManagerIFocusManagerInputElement.Focus(...)KeyboardNavigationKeyboardNavigationModeNavigationDirectionNavigationMethodFindNextElementOptionsXYFocusAccessTextImportant members:
FocusManager.Focus(...)FocusManager.TryMoveFocus(...)IFocusManager.GetFocusedElement()InputElement.IsTabStop, TabIndex, FocusableKeyboardNavigation.TabNavigationPropertyKeyboardNavigation.TabOnceActiveElementPropertyKeyboardNavigation.IsTabStopPropertyKeyboardNavigation.SetTabNavigation(...), SetTabIndex(...)XYFocus.LeftProperty, RightProperty, UpProperty, DownPropertyXYFocus.NavigationModesPropertyAccessText.ShowAccessKeyPropertyReference source files:
src/Avalonia.Controls/TopLevel.cssrc/Avalonia.Base/Input/FocusManager.cssrc/Avalonia.Base/Input/IFocusManager.cssrc/Avalonia.Base/Input/InputElement.cssrc/Avalonia.Base/Input/KeyboardNavigation.cssrc/Avalonia.Base/Input/KeyboardNavigationMode.cssrc/Avalonia.Base/Input/NavigationDirection.cssrc/Avalonia.Base/Input/NavigationMethod.cssrc/Avalonia.Base/Input/FindNextElementOptions.cssrc/Avalonia.Base/Input/Navigation/XYFocus.Properties.cssrc/Avalonia.Controls/Primitives/AccessText.csFocus is owned by the current TopLevel.
Practical model:
InputElement.Focus(...) for direct focus targeting.KeyboardNavigation attached properties to shape tab order.FocusManager.TryMoveFocus(...) for directional or tab traversal.XYFocus overrides when TV/gamepad-like directional behavior is needed.<StackPanel>
<TextBox Name="First" KeyboardNavigation.TabIndex="0" />
<TextBox Name="Second" KeyboardNavigation.TabIndex="1" />
<Button Content="Submit" KeyboardNavigation.TabIndex="2" />
</StackPanel>
<StackPanel KeyboardNavigation.TabNavigation="Cycle">
<TextBox />
<TextBox />
</StackPanel>
using Avalonia.Controls;
using Avalonia.Input;
if (TopLevel.GetTopLevel(this)?.FocusManager is FocusManager fm)
{
fm.TryMoveFocus(NavigationDirection.Next);
}
XYFocus<Button x:Name="LeftButton" XYFocus.Right="{Binding #RightButton}" />
<Button x:Name="RightButton" XYFocus.Left="{Binding #LeftButton}" />
<StackPanel>
<Label Content="_Name" Target="{Binding #NameBox}" />
<TextBox x:Name="NameBox" />
</StackPanel>
TabIndex usage minimal and local; rely on visual order where possible.KeyboardNavigation.TabNavigation on complex popups/dialog roots.NavigationMethod.Tab semantics for access-key focus feedback.XYFocus directional edges explicitly.ClearFocus() as a normal UX pattern; move focus to a valid target.Focusable is false.IsEffectivelyEnabled is false.KeyboardNavigation.IsTabStop disabled.KeyboardNavigation.TabNavigation on ancestor is None or restrictive.XYFocus overrides in sparse layouts._ marker in AccessText/label content.Default mode:
XAML-first complete example:
<StackPanel xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
KeyboardNavigation.TabNavigation="Cycle"
Spacing="6">
<TextBox x:Name="FirstNameBox" KeyboardNavigation.TabIndex="0" />
<TextBox x:Name="LastNameBox" KeyboardNavigation.TabIndex="1" />
<Button x:Name="SaveButton" KeyboardNavigation.TabIndex="2" Content="Save" />
</StackPanel>
Code-only alternative (on request):
using Avalonia.Controls;
using Avalonia.Input;
KeyboardNavigation.SetTabNavigation(formPanel, KeyboardNavigationMode.Cycle);
KeyboardNavigation.SetTabIndex(firstNameBox, 0);
KeyboardNavigation.SetTabIndex(lastNameBox, 1);
KeyboardNavigation.SetTabIndex(saveButton, 2);
TopLevel.GetTopLevel(saveButton)?.FocusManager?.Focus(firstNameBox, NavigationMethod.Tab);