如何将 shell 弹出窗口中的页面设置为仅在登录后加载?

How can I set a page in the shell flyout to only load once logged in?

我正在尝试使用 header 中的 logged-in 用户个人资料图片创建弹出菜单。我使用 api 将 url 获取到个人资料图片,但这在用户登录之前不会发生。

使用 AppShell,弹出内容似乎是在应用程序运行时立即创建的,因此它无法获取个人资料图片所需的数据。我尝试绑定到 IsLogged 属性(但不确定我是否正确实施),但即使 IsLogged 为假,它似乎仍在页面上运行代码。

如何让这个 header 部分仅在用户登录时才尝试获取图片?

AppShell.xaml

<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   xmlns:fontAwesome="clr-namespace:FontAwesome"
   xmlns:local="clr-namespace:DOTS.Views"
   xmlns:controls="clr-namespace:DOTS.Controls"
   xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
   Title="DOTS"
   x:Class="DOTS.AppShell">

<Shell.FlyoutHeader>
    <controls:FlyoutHeader IsVisible="{Binding IsLogged}"/>
</Shell.FlyoutHeader>

<!-- Login/Start Page -->
<ShellItem Route="LoginPage" FlyoutItemIsVisible="False">
    <ShellContent ContentTemplate="{DataTemplate local:LoginPage}"/>
</ShellItem>

AppShell.xaml.cs

public partial class AppShell : Shell
{
    
    public AppShell()
    {
        InitializeComponent();
        BindingContext = this;
    }

    public bool IsLogged
    {
        get => (bool)GetValue(IsLoggedProperty);
        set => SetValue(IsLoggedProperty, value);
    }

    public static readonly BindableProperty IsLoggedProperty =
BindableProperty.Create("IsLogged", typeof(bool), typeof(AppShell), false, propertyChanged: IsLogged_PropertyChanged);

    private static void IsLogged_PropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
      if ((bool) newValue)
   Shell.Current.GoToAsync($"//{nameof(MainPage)}");
else
  Shell.Current.GoToAsync($"//{nameof(LoginPage)}");

  }

FlyoutHeader.xaml

  <?xml version="1.0" encoding="UTF-8"?>
  <ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="DOTS.Controls.FlyoutHeader">
  <ContentView.Content>
    <Grid BackgroundColor="White">
        <ImageButton x:Name="ProfilePic" WidthRequest="80" HeightRequest="80" CornerRadius="40"  HorizontalOptions ="Center" Clicked ="UpdateProfile_Clicked" />
    </Grid>
</ContentView.Content>

FlyoutHeader.xaml.cs

  namespace DOTS.Controls
  {
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class FlyoutHeader : ContentView
    {
      public FlyoutHeader()
       {
        InitializeComponent();
        GetProfilePic();
      }

      public void GetProfilePic()
      {
        ProfilePic.Source = (string)Application.Current.Properties["picUrl"];
       //This value is set upon login
      }
    }
  }

在您的 AppShell 中,当 IsLogged 值更改为 true 时,调用 GetProfilePic() 方法:

public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
        BindingContext = this;
    }

    public bool IsLogged
    {
        get => (bool)GetValue(IsLoggedProperty);
        set => SetValue(IsLoggedProperty, value);
    }

    public static readonly BindableProperty IsLoggedProperty =
BindableProperty.Create("IsLogged", typeof(bool), typeof(AppShell), false, propertyChanged: IsLogged_PropertyChanged);

    private static async void IsLogged_PropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
      if ((bool) newValue)
      {
         await Shell.Current.GoToAsync($"//{nameof(MainPage)}");
         (Current.FlyoutHeader as FlyoutHeader)?.GetProfilePic();
      }

      else
         await Shell.Current.GoToAsync($"//{nameof(LoginPage)}");
  }

FlyoutHeader.xaml.cs 上对 IsLogged 进行测试:

namespace DOTS.Controls
  {
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class FlyoutHeader : ContentView
    {
      public FlyoutHeader()
       {
        InitializeComponent();
        GetProfilePic();
      }

      public void GetProfilePic()
      {
        if ( (Shell.Current as AppShell).IsLogged)
             ProfilePic.Source = (string)Application.Current.Properties["picUrl"];
       //This value is set upon login
      }
    }
  }