.NET MAUI中如何在Unfocused事件处理器内获取新获焦元素
解决方案:判断新获焦元素类型以控制Entry焦点
在MAUI的Unfocused事件中确实无法直接获取新获焦的元素,但可以通过以下两种方法实现你的需求:
方法1:延迟遍历可视树查找当前焦点元素
因为Unfocused事件触发时,新元素的焦点可能还未完全生效,所以需要短暂延迟后,遍历整个可视树找到当前拥有焦点的元素,再判断其类型。
修改你的SearchBar.xaml.cs代码如下:
using System.ComponentModel; using Microsoft.Maui.Controls; namespace SomeApp.Src.Components; public partial class SearchBar : ContentView { public SearchBar() { InitializeComponent(); SearchField.Unfocused += OnLostFocus; } private async void OnLostFocus(object sender, FocusEventArgs e) { // 短暂延迟,确保新焦点元素已完成焦点设置 await Task.Delay(100); // 查找当前拥有焦点的元素 var focusedElement = FindFocusedElement(Application.Current.MainPage); // 如果新焦点不是Entry,重新聚焦当前SearchField if (focusedElement is not Entry) { SearchField.Focus(); } } // 递归遍历可视树查找焦点元素 private VisualElement FindFocusedElement(VisualElement parent) { if (parent.IsFocused) return parent; foreach (var child in parent.Children) { if (child is VisualElement visualChild) { var focusedChild = FindFocusedElement(visualChild); if (focusedChild != null) return focusedChild; } } return null; } public void FocusSearchField() { SearchField.Focus(); } }
方法2:全局监听焦点变化,记录当前焦点元素
在应用启动时或者页面初始化时,监听所有元素的Focused事件,维护一个全局变量存储当前焦点元素,这样在Unfocused事件中可以直接读取该变量判断类型。
步骤1:在App.xaml.cs中添加全局变量和监听
namespace SomeApp; public partial class App : Application { public static VisualElement CurrentFocusedElement { get; set; } public App() { InitializeComponent(); // 监听全局焦点变化 FocusManager.Focused += OnGlobalFocused; } private void OnGlobalFocused(object sender, FocusEventArgs e) { CurrentFocusedElement = e.VisualElement; } protected override void OnTerminating() { // 移除监听避免内存泄漏 FocusManager.Focused -= OnGlobalFocused; base.OnTerminating(); } }
步骤2:修改SearchBar的OnLostFocus方法
private void OnLostFocus(object sender, FocusEventArgs e) { // 判断当前全局焦点元素是否为Entry if (App.CurrentFocusedElement is not Entry) { SearchField.Focus(); } }
注意事项
- 方法1的延迟时间可根据实际情况调整,确保新焦点元素已完成焦点设置。
- 方法2需在应用终止时移除全局监听,避免内存泄漏。
内容的提问来源于stack exchange,提问作者GorkhaDK
相关产品推荐
相关产品推荐

