简体   繁体   中英

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

I am trying to create a flyout menu with the logged-in users profile picture in the header. I use an api to get the url to the profile pic, but this can't happen until the user is logged in.

Using AppShell, it seems the flyout content is created as soon as the app runs, so it can't get the data it would need for the profile picture. I tried binding to the IsLogged property (but not sure I implemented that correctly), but it seems it's still runs the code on the page even when IsLogged is false.

How can I get this header section to only try to get the picture if the user is logged in?

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
      }
    }
  }

In your AppShell, upon IsLogged value change to true, call the GetProfilePic() method:

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)}");
         (Current.FlyoutHeader as FlyoutHeader)?.GetProfilePic();
      }

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

In FlyoutHeader.xaml.cs do a test on IsLogged :

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM