.NET Maui中GoToAsync调用时显示BusyIndicator的正确方法
解决.NET MAUI中GoToAsync时SfBusyIndicator不显示的问题
问题根源
设置Loading = true后,紧接着执行的await GoToAsync(以及详情页后续的数据库同步操作)会占据UI线程,导致UI来不及刷新BusyIndicator的状态。等UI线程空闲下来处理状态更新时,Loading已经被设为false,所以看不到指示器。
解决方案
方案1:先让UI完成状态更新再执行导航
在设置Loading = true后,通过Task.Yield()让UI线程优先处理状态刷新,再执行导航操作:
Loading = true; // 让出UI线程,确保BusyIndicator状态更新完成 await Task.Yield(); await Shell.Current.GoToAsync($"//people/person", new Dictionary<string, object> { { "Person", person } }); Loading = false;
Task.Yield()会让当前的异步操作暂停,把控制权交还给UI线程,完成Pending的UI更新后再继续执行后续代码。
方案2:将数据加载逻辑移到详情页并控制加载状态
既然延迟来自详情页的数据库额外信息拉取,更合理的做法是在详情页的ViewModel中处理加载逻辑,让BusyIndicator在详情页显示,而非列表页:
- 在详情页ViewModel中添加加载方法:
public async Task LoadExtraPersonData(Person person) { Loading = true; // 用Task.Run将数据库操作放到后台线程,避免阻塞UI var extraInfo = await Task.Run(() => _yourDbService.GetExtraInfo(person.Id)); // 更新详情页数据 CurrentPersonExtraInfo = extraInfo; Loading = false; }
- 导航到详情页后,传递Person参数并调用加载方法:
列表页导航代码保持简洁:
await Shell.Current.GoToAsync($"//people/person", new Dictionary<string, object> { { "Person", person } });
详情页接收参数后触发加载:
protected override async void OnNavigatedTo(NavigatedToEventArgs args) { base.OnNavigatedTo(args); if (Navigation.Parameter is Person person) { await ViewModel.LoadExtraPersonData(person); } }
这种方式更符合用户直觉——用户点击列表项后跳转至详情页,此时在详情页显示加载指示器,明确告知用户正在加载详情信息。
额外检查
确保你的ViewModel实现了INotifyPropertyChanged接口,并且Loading属性的Setter会触发PropertyChanged事件,这样UI才能响应状态变化:
private bool _loading; public bool Loading { get => _loading; set { _loading = value; OnPropertyChanged(nameof(Loading)); } }
内容的提问来源于stack exchange,提问作者AJ.
相关产品推荐
相关产品推荐

