Xamarin Forms best way to force display of one page from another

Charles Mills 26 Reputation points
2021-08-18T23:19:07.16+00:00

This is my first Xamarin Forms app. It's not MVVM; I am tackling one learning curve at a time. VS 2019 Windows; project is Android/UWP and hopefully iOS.

I started from the Flyout menu template. The app is pretty much all working.

Under certain circumstances rather than loading the page the user requested from the Flyout Menu I want to display an "authentication" page to force the user to enter a password (or on Android scan his or her fingerprint if reader is available).

So what I am doing is in the Appearing method of the various pages I am checking for the need to authenticate and if so doing a PushModalAsync(new AuthenticationPage) and then when authentication completes doing a PopModalAsync(). I disable the Back button and so forth to keep the user on the password page until the password is entered successfully.

The problem is that PopModalAsync() seems to load a new instance of the original page? Is that correct? I seem to have a mess that I don't quite understand. Am I doing this the best way? I took a look at https://social.msdn.microsoft.com/Forums/en-US/904d1d72-8d14-417f-875f-0a2f3a73ea11/how-to-cancel-a-page-loading-during-onappearing?forum=xamarinforms but that got me down a rabbit hole. Is there a better way?

Developer technologies | .NET | Xamarin
0 comments No comments
{count} votes

Answer accepted by question author
  1. Kyle Wang 5,531 Reputation points Microsoft External Staff
    2021-08-19T09:10:52.073+00:00

    Hi CharlesMills-5302,

    Welcome to our Microsoft Q&A platform!

    Since login is not a frequent operation, creating a new instance will not take up much memory.

    If you want to avoid creating new instance every time, here is a workaround that you can create a custom login ContentView and add it into the Page, then set its "IsVisible" property.

    Here is a simple example you can refer to.
    LoginView.xaml

    <ContentView ...  
                 xmlns:local="clr-namespace:WayToPopLoginPage.Views">  
        <ContentView.Content>  
            <StackLayout>  
                <Entry Placeholder="User Name"/>  
                <Entry Placeholder="Password"/>  
                <Button Text="login" Command = "{Binding Source={RelativeSource AncestorType={x:Type local:ItemsPage}}, Path=ShowCommand}"/>  
            </StackLayout>  
        </ContentView.Content>  
    </ContentView>  
    

    ItemPage.xaml (Show info in this page)

    <ContentPage ...>  
        <Grid RowDefinitions="*">  
            <StackLayout IsVisible="{Binding Login}" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">  
                    <Label Text="Content here"/>  
            </StackLayout>  
      
            <localview:LoginView IsVisible="{Binding Notlogin}" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>  
        </Grid>  
    </ContentPage>  
    

    ItemsPage.xaml.cs

    public partial class ItemsPage : ContentPage, INotifyPropertyChanged  
    {  
        public ItemsPage()  
        {  
            InitializeComponent();  
            ShowCommand = new Command(Show);  
            BindingContext = this;  
        }  
      
        protected override void OnAppearing()  
        {  
            base.OnAppearing();  
            Login = Preferences.Get("logged", false);  
            Notlogin = !Preferences.Get("logged", false);  
        }  
      
        public ICommand ShowCommand { get; }  
      
        bool notlogin;  
        public bool Notlogin  
        {  
            get => notlogin;  
            set  
            {  
                notlogin = value;  
                OnPropertyChanged("Notlogin");  
            }  
        }  
      
        bool login;  
        public bool Login  
        {  
            get => login;  
            set  
            {  
                login = value;  
                OnPropertyChanged("Login");  
            }  
        }  
      
        private void Show()  
        {  
            Login = true;  
            Notlogin = false;  
            Preferences.Set("logged", true);  
        }  
      
        public event PropertyChangedEventHandler PropertyChanged;  
      
        protected void OnPropertyChanged(string propertyName)  
        {  
            var handler = PropertyChanged;  
            if (handler != null)  
                handler(this, new PropertyChangedEventArgs(propertyName));  
        }  
    }  
    

    Regards,
    Kyle


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.