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

如何从绑定属性中调用SecureStorage.GetAsync方法

解决Flyout绑定异步SecureStorage数据的最佳方案

你的代码无法运行的核心原因是:C#属性的getter不支持异步操作,不能在同步的get方法中使用await,也无法直接返回Task<string>类型。下面是几种可行的实现方式,推荐结合MVVM模式的方案:

方案一:基于CommunityToolkit.Mvvm的异步加载(推荐)

利用MVVM工具包的ObservableObject自动实现属性通知,在Shell初始化时异步加载用户信息:

  1. 确保项目引用了CommunityToolkit.Mvvm NuGet包
  2. 修改AppShell代码:
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Maui.Storage;

public partial class AppShell : Shell
{
    // 自动生成ObservableProperty,包含属性变更通知
    [ObservableProperty]
    private string _userEmail = "未登录";

    [ObservableProperty]
    private string _userFirstName = "未登录";

    public AppShell()
    {
        InitializeComponent();
        BindingContext = this;
        // 异步加载用户信息,用丢弃运算符避免编译器警告
        _ = LoadUserProfileAsync();
    }

    private async Task LoadUserProfileAsync()
    {
        // 从SecureStorage异步获取数据,为空时显示默认文本
        UserEmail = await SecureStorage.GetAsync("email") ?? "未登录";
        UserFirstName = await SecureStorage.GetAsync("firstName") ?? "未登录";
    }
}
  1. 在Flyout的XAML中绑定属性:
<StackLayout>
    <Label Text="{Binding UserFirstName}" FontSize="Headline"/>
    <Label Text="{Binding UserEmail}" FontSize="Caption"/>
</StackLayout>

方案二:手动实现INotifyPropertyChanged(无MVVM框架)

如果不想引入第三方包,可以手动实现属性变更通知:

using Microsoft.Maui.Storage;
using System.ComponentModel;
using System.Runtime.CompilerServices;

public partial class AppShell : Shell, INotifyPropertyChanged
{
    private string _userEmail = "未登录";
    public string UserEmail
    {
        get => _userEmail;
        set
        {
            if (_userEmail != value)
            {
                _userEmail = value;
                OnPropertyChanged();
            }
        }
    }

    private string _userFirstName = "未登录";
    public string UserFirstName
    {
        get => _userFirstName;
        set
        {
            if (_userFirstName != value)
            {
                _userFirstName = value;
                OnPropertyChanged();
            }
        }
    }

    public AppShell()
    {
        InitializeComponent();
        BindingContext = this;
        _ = LoadUserProfileAsync();
    }

    private async Task LoadUserProfileAsync()
    {
        UserEmail = await SecureStorage.GetAsync("email") ?? "未登录";
        UserFirstName = await SecureStorage.GetAsync("firstName") ?? "未登录";
    }

    // 手动实现属性变更通知
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

处理登录后的信息更新

当用户登录成功后,需要及时更新Flyout中的信息,有两种方式:

方式1:直接调用Shell的加载方法

在登录页面的登录成功逻辑中:

// 存储用户信息到SecureStorage
await SecureStorage.SetAsync("email", inputEmail);
await SecureStorage.SetAsync("firstName", inputFirstName);

// 获取当前Shell实例并重新加载信息
if (Application.Current.MainPage is AppShell shell)
{
    await shell.LoadUserProfileAsync();
}

方式2:用消息通知解耦(推荐)

利用CommunityToolkit.Mvvm的Messenger实现跨页面通信,避免直接依赖Shell:

  1. 定义消息类:
public class UserProfileUpdatedMessage
{
}
  1. 在AppShell中注册消息监听:
public AppShell()
{
    InitializeComponent();
    BindingContext = this;
    _ = LoadUserProfileAsync();

    // 监听用户信息更新消息
    WeakReferenceMessenger.Default.Register<UserProfileUpdatedMessage>(this, (sender, message) =>
    {
        _ = LoadUserProfileAsync();
    });
}
  1. 登录成功后发送消息:
await SecureStorage.SetAsync("email", inputEmail);
await SecureStorage.SetAsync("firstName", inputFirstName);

// 发送更新消息
WeakReferenceMessenger.Default.Send(new UserProfileUpdatedMessage());

内容的提问来源于stack exchange,提问作者jstuardo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:56:24