You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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在详情页显示,而非列表页:

  1. 在详情页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;
}
  1. 导航到详情页后,传递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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:40:36