LoginPage with FreshMVVM ?

Marco_SeraphinMarco_Seraphin DEUniversity ✭✭

Hello,

what is the best way to implement a Login page with FreshMVVM ?

Any sample or suggestion ?

Thank you

Marco

Answers

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    you can try to ask to @MichaelRidland

  • MichaelRidlandMichaelRidland AUInsider, University ✭✭✭

    @MarcoSeraphin.5371

    There's a few different way to do this.

    1) You can set your MainPage to the main application navigation (eg Tabbed/MasterDetail), and then show a login page modal.

    2) You can have two NavigationStacks, a LoginStack and a MainStack and switch them out using

    //Setup names for you navigation stacks
    public class NavigationStacks
    {
      public static string LoginNavigationStack = "LoginNavigationStack";
      public static string MainAppStack = "MainAppStack";
    }
    
    //Setup your login Navigation Stack
    var welcomePage = FreshPageModelResolver.ResolvePageModel<WelcomePageModel> ();
    var loginStack = new FreshNavigationContainer (welcomePage, NavigationStacks.LoginNavigationStack);
    
    //Switch out to your main stack once you've authenticated. 
    CoreMethods.SwitchOutRootNavigation (NavigationStacks.MainAppStack)
    

    Thanks

    Michael

  • Marco_SeraphinMarco_Seraphin DEUniversity ✭✭
    edited July 2016

    Hi Michael,

    thanx for your fast answer. I tried out the solution with the Modal page in the ViewAppearing of the MasterDetail Page where I check a IsLoggedIn flag.

    Here some code from my MasterMenuPageModel (the MasterDetail Page View Model)

    protected override void ViewIsAppearing(object sender, EventArgs e)
    {
         base.ViewIsAppearing(sender, e);
    
         if (App.IsLoggedIn == false)
         {
              CoreMethods.PushPageModel<LoginPageModel>(null, true, true);
         }
    }
    

    Best

    Marco

  • I tried the same thing. Worked. However I'm stuck on the closing this page. In the Button Command code below I have tried Pop and Push. I'm guessing being inside the async Command is part of the issue. How do I get back /out of Model page when user has logged in successfully?

    public Command SetLogin
    {
    get
    {
    return new Command(async () =>
    {
    // Message = "Jobnumber: " + JobNumber + " and MCL#: " + FmNumber;

                    _userDialogs.ShowLoading();
                    try
                    {
                        UserLogins = await _dataService.GetUserLogin(_LoginText, _passwordText);
                        if (UserLogins.Any())
                        {
                           Message =  UserLogins.First().DisplayName +  " is logged In!";
                            App.IsLoggedIn = true;
                            App.AppCurr_UserLogin = UserLogins.First();
                            await CoreMethods.PushPageModel<MenuMainPageModel>(null, false, true);
    
  • MichaelRidlandMichaelRidland AUInsider, University ✭✭✭

    It depends on how you've shown the page.

    -If you've pushed then you need to pop
    -If you've push modal then you need to pop modal
    -If you've switch container then you need to switch container back

    Thanks

  • Hi @MarcoSeraphin, im interested with your project. can u give me some code for example to learn about login in XF?
    im still don't have any example.
    i hope you'll help me, thanks :)

  • Marco_SeraphinMarco_Seraphin DEUniversity ✭✭

    Hi Muhammad,

    I did it like @MichaelRidland described with a modal login page which I pushed modal like this:

    App.IsLoggedIn = false;
    await CoreMethods.PushPageModel<LoginPageModel>(null, true, true);
    

    In my case I try a REST service based log on the LogIn Page and than set the App.IsLoggedIn to true. After successful login I set the MainPage to my initial navigation container (FreshMVVM container)

    Best

    Marco

  • @MarcoSeraphin.5371 im still confuse if just some code like that, im sorry before im just very very newbie in XF. im learning by doing. i also looking for XF login example with MVVM but until now im still confused. maybe your code can be the example for me.

    can u share youre code? for increase my knowledge. Thank you :)

    Regards,

    Muhammad S.N

  • Marco_SeraphinMarco_Seraphin DEUniversity ✭✭

    Hi Muhammad,

    sorry for saying this. But this is code of my client and of course HIS property, not mine. Additionally I have signed a lot of data protection papers.....so sorry, but not chance to share more code than this snippet.

    Best

    Marco

  • Thanks Michael, that was a Doh! moment. I had pushed it Model and tried Poping it Model but I think I tried the first parameter as false and it didn't work so I tried the other Pop methods to no avail. Devil in the details. So the below call worked. Thanks again. So can you explain the functionality of the first parameter in this method? Maybe I will look at the source.
    await CoreMethods.PopPageModel(true, true);

  • OK on to another question. Login working. Now I have another Page which must be called if Another App Object is not set. This page is basically the Project-Task Context. So it must be called if the App.ProjectTask Object is not set. This Page is also available in the Menu page, as people can use it to switch the Project Task Context. So if the user hits a page that needs it, I have:
    protected override void ViewIsAppearing(object sender, EventArgs e)
    {
    base.ViewIsAppearing(sender, e);

                if (App.IsMCLSeleced == false)
                {
                    CoreMethods.PushPageModel<SetJobMCLPageModel>(null, true, true);
                }
            }
    

    However in the SetJobMCLPageModel, if the Project-Task Context is Set correctly, how do I know if this page was called modally and needs to be Popped? I tried below but it did not work (in the button method to set the ProjectTask Context).

       if(this.IsModalAndHasPreviousNavigationStack())
                            { await CoreMethods.PopPageModel(true, true); }
    

    Suggestions...

  • Just to clarify my babbling...when executing code on a Page, programmatically how can I tell if a page was pushed as a modal page from code as opposed to being pushed non-modally from a menu selection?

  • I went with the two Navigation stacks, it seemed to be the easiest to implement for my type of functionality.

  • DavidTavarezDavidTavarez DOMember ✭✭✭

    Everybody should using Prism https://github.com/PrismLibrary/Prism

  • CodeGrueCodeGrue USMember ✭✭
    edited January 12

    @MichaelRidland I'm having an issue using the named navigation stack technique and a master-detail stack. The issue is once SwitchOutRootNavigation is called to go to the master-detail stack, calling PushPageModel from the landing page (or assuming any page in that stack) doesn't do anything. It's like it doesn't know about FreshMvvm anymore.

    Here is the code for the two named stacks.

    // Setup welcome/login Navigation Stack
    var welcomePage = FreshPageModelResolver.ResolvePageModel<WelcomeViewModel>();
    var welcomeStack = new FreshNavigationContainer(welcomePage, "WelcomeNavigationStack");
    welcomeStack.BarTextColor = Color.White;
    
    // Setup main Navigation Stack
    var mainStack = new FreshMasterDetailNavigationContainer("MainNavigationStack");
    mainStack.Master = FreshPageModelResolver.ResolvePageModel<MenuViewModel>();    
    mainStack.Detail = new FreshNavigationContainer(FreshPageModelResolver.ResolvePageModel<DashboardViewModel>());
    

    And the symptom happens when you call the following from within the WelcomeViewModel to switch to the MenuViewModel/DashboardViewModel:

    CoreMethods.SwitchOutRootNavigation("MainNavigationStack");
    

    Then the following doesn't work from DashboardViewModel. Can confirm with a breakpoint that it gets called, but nothing happens, not even an error of any kind:

    CoreMethods.PushPageModel<AnotherViewModel>();
    
  • CodeGrueCodeGrue USMember ✭✭

    In the above scenario, I traced the issue to having a bug in the target page XAML. FreshMVVM doesn't halt execution or raise an exception with the call to PushPageModel, rather nothing at all happens. No indication of any kind there is an issue.

  • MichaelRidlandMichaelRidland AUInsider, University ✭✭✭

    @CodeGrue I can see the issue is that the master detail needs to be setup differently.

    Please see and let me know if this resolves the issue.
    https://github.com/rid00z/FreshMvvm#master-detail---built-in

  • CodeGrueCodeGrue USMember ✭✭

    SOLVED. Posting solution in case it can help anyone else.

    @MichaelRidland I didn't think it was related to the master-detail configuration so I made a new minimal project to reproduce the issue. Here is the code I used:

    App.xaml.cs:

    public App()
    {
        InitializeComponent();
    
        // This code will not raise an exception when showing the "invalid" page
        var page = FreshPageModelResolver.ResolvePageModel<WelcomeViewModel>();
        var container = new FreshNavigationContainer(page);
        MainPage = container;
    }
    

    WelcomePage.xaml:

        <ContentPage.Content>
            <StackLayout>
                <Button Text="Valid Page" Command="{Binding ValidCommand}" />
                <Button Text="Invalid Page" Command="{Binding InvalidCommand}"   />           
            </StackLayout>           
        </ContentPage.Content>
    

    WelcomeViewModel.cs:

        public class WelcomeViewModel : FreshBasePageModel
        {    
            public Command InvalidCommand
            {
                get => new Command(() => CoreMethods.PushPageModel<InvalidViewModel>());
            }
    
            public Command ValidCommand
            {
                get => new Command(() => CoreMethods.PushPageModel<ValidViewModel>());
            }
        }
    

    ValidPage.xaml:

        <ContentPage.Content>
            <Label Text="Valid Page" />               
        </ContentPage.Content>
    

    InvalidPage.xaml:

        <ContentPage.Content>
                <Label Text="Invalid Page" BadTag="error should be caught" />         
        </ContentPage.Content>
    

    The problem was in how the commands were set up. Without the async/await clauses, no error gets reported back. So the correct code for WelcomeViewModel.cs needs to be this:

        public class WelcomeViewModel : FreshBasePageModel
        {
            public Command InvalidCommand
            {
                get => new Command(async () => await CoreMethods.PushPageModel<InvalidViewModel>());
           }
    
            public Command ValidCommand
            {
                get => new Command(async () => await CoreMethods.PushPageModel<ValidViewModel>());
            }
        }
    
Sign In or Register to comment.