Avalonia焦点管理依托FocusManager类与控件API协同实现,核心是区分逻辑焦点与键盘焦点;通过visual.FocusManager()获取实例,调用SetFocusedElement或控件.Focus()设焦点,监听GotFocus/LostFocus响应键盘焦点变化,TabIndex和IsTabStop控制Tab导航顺序。
Avalonia 中的焦点管理主要通过 FocusManager 类和控件自身的焦点相关属性/方法协同完成,核心是理解“逻辑焦点”与“键盘焦点”的分离机制,并合理使用 API 主动控制或响应焦点变化。
FocusManager 是 Avalonia 中负责统一管理焦点的核心类,每个 VisualTree(
如 Window 或 UserControl)都拥有自己的 FocusManager 实例。它不直接暴露为全局单例,而是通过控件树向上查找获得:
IVisual(如 Button, TextBox)出发,可用 visual.FocusManager() 扩展方法获取其所属视觉树的 FocusManager
Window.GetFocusManager() 或 Application.Current?.FocusManager(全局默认)访问,但通常推荐按作用域获取,避免跨窗口误操作调用 FocusManager.SetFocusedElement 是最直接的焦点设置方式,但需注意前提条件:
IsAttachedToVisualTree == true),否则调用无效IsFocusable == true(默认多数输入控件为 true,布局容器如 Panel 默认为 false)window.FocusManager().SetFocusedElement(myTextBox);
此外,控件自身也提供便捷方法:myTextBox.Focus(); 内部即调用其所在 FocusManager 完成设置,语义更清晰,推荐优先使用。
Avalonia 控件提供两个关键路由事件用于响应焦点变化:
GotFocus:当控件获得键盘焦点时触发(注意:不是逻辑焦点)LostFocus:当控件失去键盘焦点时触发Grid 上监听所有子控件的焦点切换注意:GotFocus/LostFocus 只反映键盘焦点(即用户按 Tab 或点击触发的焦点),不涵盖通过 FocusManager 设置的逻辑焦点。若需监听逻辑焦点变化,应绑定控件的 IsFocused 属性(INotifyPropertyChanged)。
Avalonia 默认支持 Tab 导航,顺序由控件在 XAML 中的声明顺序决定。可通过以下方式干预:
TabIndex 属性:设置整数索引,值越小越先获得焦点;未设置者按文档顺序排在最后IsTabStop="False":排除该控件参与 Tab 导航(如仅作装饰的 TextBlock)OnKeyDown 捕获 Key.Tab 并手动调用 FocusManager.MoveFocus 可实现完全自定义跳转逻辑(例如表单内按回车切到下一字段)不复杂但容易忽略。