Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Maui RoutedViewModel, NavigateAndReset doesn't change views (for Windows at least) #3939

Open
limefrogyank opened this issue Dec 13, 2024 · 3 comments
Labels

Comments

@limefrogyank
Copy link
Contributor

limefrogyank commented Dec 13, 2024

Describe the bug 🐞

I'm using Maui Hybrid on Windows. I'm using both Maui native views and some Blazor views, too. I've got a ReactiveUI.Maui.RoutedViewHost to control the navigation via native views. I have some code that runs on startup that checks for a login status and changes the start page based on that:

d2lService.HasAccess.ObserveOn(RxApp.MainThreadScheduler).Subscribe(async x =>
            {
                if (x)
                {
                    Router
                        .NavigateAndReset
                        .Execute(new RootViewModel())
                        .Subscribe();
                }
                else
                {
                    Router
                       .NavigateAndReset
                       .Execute(new WebViewViewModel())
                       .Subscribe();
                }
            });

This part works just fine. If my token is no longer valid, my HasAccess observable will return false and the app will start with a page that contains a WebView. If I do have access, the start page is a page that contains more complicated stuff.

What doesn't work is the transition between the two. When I "log in" via the webview page and then the HasAccess observable flips, the viewmodel changes but the view stays the same. i.e. I now have a RootViewModel in the stack, but the view is still for the WebViewViewModel.

Step to reproduce

Create an AppBootstrapper.cs containing this:

internal class AppBootstrapper : ReactiveObject, IScreen
    {
        //private static required IDisposable _d;

        public RoutingState Router { get; protected set; }

        public BehaviorSubject<bool> HasAccess = new BehaviorSubject<bool>(false);
        
        public AppBootstrapper()
        {
            Router = new RoutingState();
            Locator.CurrentMutable.RegisterConstant(this, typeof(IScreen));

            Locator.CurrentMutable.Register(() => new WebViewView(), typeof(IViewFor<WebViewViewModel>)); // webview for logging in
            Locator.CurrentMutable.Register(()=> new RootPage(), typeof(IViewFor<RootViewModel>)); // root page

 Observable.Timer(TimeSpan.FromSeconds(20)).Subscribe(x=> HasAccess.OnNext(true));

            HasAccess.ObserveOn(RxApp.MainThreadScheduler).Subscribe(async x =>
            {
                if (x)
                {
                    Router
                        .NavigateAndReset
                        .Execute(new RootViewModel())
                        .Subscribe();
                }
                else
                {
                    Router
                       .NavigateAndReset
                       .Execute(new WebViewViewModel())
                       .Subscribe();
                }
            });

        }

        public static ReactiveUI.Maui.RoutedViewHost CreateMainPage(RoutingState router)
        {
            var host = new ReactiveUI.Maui.RoutedViewHost();
            host.Router = router;
            return host;
        }

    }

You'll then have to create two pages (ReactiveContentPage) and viewmodels that implement IRoutableViewModel. The page should start with one, then the timer should try to reset navigation to the new page.

Reproduction repository

https://github.com/reactiveui/ReactiveUI

Expected behavior

You should see two different pages with an interval of 20 seconds between them.

Screenshots 🖼️

No response

IDE

No response

Operating system

Windows

Version

11 latest non-dev

Device

No response

ReactiveUI Version

20.1.63

Additional information ℹ️

No response

@limefrogyank
Copy link
Contributor Author

MauiApp1.zip

@limefrogyank
Copy link
Contributor Author

The project above should demonstrate the issue. After 20 seconds, it will try to switch to a new page using NavigateAndReset and do nothing. If you replace the NavaigateAndReset with a plain Navigate, navigation works as intended, but the back stack contains the old page... not what I need. Thanks!

@limefrogyank
Copy link
Contributor Author

FYI, I've been having a lot of problems with NET9 and downgraded to NET8 for this sample project. So it's not the dotnet version...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant