0

I want to have MAUI page transition so it feels more native. When I create CounterPage.xaml for "Counter" page and I register it as singleton and then try to navigate with await App.Current.MainPage.Navigation.PushModalAsync(new CounterPage()); it always load whole app with quick flash "Loading..." (like WASM). What am I doing wrong? Is it because of "new CounterPage()"?

Index.razor

@page "/"

<h1>Index</h1>

<button class="btn btn-secondary" @onclick="NavigateToCounterPage">MAUI navigation Counter</button>

@code {
    async void NavigateToCounterPage()
    {
        await App.Current.MainPage.Navigation.PushModalAsync(new CounterPage());
    }
}

CounterPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:pages="clr-namespace:MAUIBlazorMAUIPageTransition.Pages"
             x:Class="MAUIBlazorMAUIPageTransition.CounterPage"
             Title="CounterPage">
    <BlazorWebView HostPage="wwwroot/index.html">
        <BlazorWebView.RootComponents>
            <RootComponent Selector="#app" ComponentType="{x:Type pages:Counter}" />
        </BlazorWebView.RootComponents>
    </BlazorWebView>
</ContentPage>

CounterPage.xaml.cs

namespace MAUIBlazorMAUIPageTransition;

public partial class CounterPage : ContentPage
{
    public CounterPage()
    {
        InitializeComponent();
    }
}

MauiProgram.cs

builder.Services.AddSingleton<CounterPage>();

I tried everything I could think of. Thank you.

Laftek
  • 33
  • 3
  • Have you worked it out? – Liqun Shen-MSFT Dec 05 '22 at 09:31
  • Sorry for late reply I had something going on. So right now I am using this method below but it creates new instance every time and its not that good. Page transition is quite nice now though. `async void NavigateToCounterPage() { await App.Current.MainPage.Navigation.PushAsync(new CounterPage()); }` Also in app.xaml.cs you need to define MainPage like new NavigationPage -> `MainPage = new NavigationPage(new MainPage());` – Laftek Feb 05 '23 at 17:03

1 Answers1

0

First, any call with Modal in the name is used to show something that later you will return from. You want to go forward, then be able to go forward again later.

Don't use that call; probably use GoToAsync.


Second, as you suspect, new CounterPage isn't what you want; it constructs a new page, which means it constructs a new BlazorWebView, which (I assume) results in what you see.

You've done half of what is needed to re-use CounterPage:

builder.Services.AddSingleton<CounterPage>();

The other half is to ask for that again.

I'm not finding doc that explains how to get at Maui's ServiceProvider; with help from Gerald Versluis, here is a way to remember ServiceProvider when app starts:

// In app.xaml.cs (the cross-platform App class, where MainPage is set\):
    public static IServiceProvider Services;

    public App(IServiceProvider provider)
    {
        InitializeComponent();

        Services = provider;

        MainPage = ...
    }

Now can access a service as needed:

var page = App.Services.GetRequiredService<CounterPage>();
await App.Current.MainPage.Navigation.GoToAsync(page);
ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
  • 1
    Thank you ToolmakerSteve! Sorry I didnt have time to look at it but I just quickly checked and its not really working for me but you gave me an idea and now its much better. I will update my answer with more details later. Thank you again! – Laftek Nov 26 '22 at 20:49
  • I've added to answer the piece I was missing. Now code shows how to ask for `CounterPage` again. Because you declared that service as a singleton (`...AddSingleton...`), this will get a reference to the same instance of `CounterPage`, instead of creating a new one each time. – ToolmakerSteve Dec 11 '22 at 02:21