maui.net-maui.shell

Maui: Why the content inside the Shell.TitleView disappears every second time?


I have a MAUI app with a Flyout menu.

In the navigation bar beside the burger I show the title and a button (navigating to the user's profile settings). When I open the app on Android device or Android emulator every second page I enter from the menu, the content inside the Shell.TitleView disappears.

The order of the selected pages does not matter. That means for example, if I open FirstPage, ThirdPage, SecondPage, FirstPage in this order, then ThirdPage and the second opening of FirstPage has no content in Shell.TitleView.

The same happens, when I use a HorizontalStackLayout. But when I use just a Label directly in Shell.TitleView (without a container like a Grid) then it works fine and on any page the Label is visible. It also works fine on Windows Machine.

It is also interesting that when I open a second page, the content of the Grid is displayed correctly for a short moment (matching title of the page), but disappears after about 0.7 seconds.

What is the problem and how it can be solved? Does anyone know of a workaround?

You can find the full example project here: https://mehlhop.com/forum/ProfileApp.7z (113 KB)

A video (kind of screencast) you find here (without download): https://mehlhop.com/forum/20230522_181856_1.mp4

AppShell.xaml:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:views="clr-namespace:ProfileApp.Views"
    x:Class="ProfileApp.AppShell"
    FlyoutBehavior="Flyout">

    <Shell.TitleView>
        <Grid ColumnDefinitions="*,*" BackgroundColor="Red">
            <Label Grid.Column="0" x:Name="title" Style="{StaticResource labelPageTitle}"/>
            <Button Grid.Column="1" Text="NN" Style="{StaticResource ButtonToProfilePage}" Clicked="ProfileButton_OnClickedAsync"/>
        </Grid>
    </Shell.TitleView>

    <FlyoutItem Title="First" >
        <ShellContent ContentTemplate="{DataTemplate views:FirstPage}" />
    </FlyoutItem>

    <FlyoutItem Title="Second">
        <ShellContent ContentTemplate="{DataTemplate views:SecondPage}" />
    </FlyoutItem>

    <FlyoutItem Title="Third">
        <ShellContent ContentTemplate="{DataTemplate views:ThirdPage}" />
    </FlyoutItem>

</Shell>

AppShell.xaml.cs:

using ProfileApp.Views;

namespace ProfileApp;

public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
        Routing.RegisterRoute(nameof(ProfilePage), typeof(ProfilePage));
    }

    protected override void OnNavigated(ShellNavigatedEventArgs args)
    {
        base.OnNavigated(args);
        title.Text = Shell.Current.CurrentItem.Title;
    }

    private async void ProfileButton_OnClickedAsync(object sender, EventArgs e)
    {
        if (Shell.Current.CurrentPage is ProfilePage) return;

        await Shell.Current.GoToAsync(nameof(ProfilePage), true);
        title.Text = "Profile Settings";
    }
}

MauiProgram.cs (detail):

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
        });

    var services = builder.Services;
    services.AddTransient<AppShell>();
    services.AddTransient<FirstPage>();
    services.AddTransient<SecondPage>();
    services.AddTransient<ThirdPage>();
    services.AddTransient<ProfilePage>();
}

Solution

  • Here is a workaround. The problem with the disappearing of the TitleView does not happen, when you reorganise the menu navigation.

    Part of AppShell.xaml:

    <Shell.FlyoutHeader>
        <views:FlyoutHeader />
    </Shell.FlyoutHeader>
    
    // defines the start page
    <ShellContent FlyoutItemIsVisible="False" ContentTemplate="{DataTemplate views:FirstPage}" Route="FirstPage"/>
    
    <MenuItem ClassId="FirstPage" Text="First" Clicked="MenuItem_OnClicked" />
    
    <MenuItem ClassId="SecondPage" Text="Second" Clicked="MenuItem_OnClicked" />
    

    Part of AppShell.xaml.cs:

    public AppShell(/*...*/)
    {
        //...
        Routing.RegisterRoute(nameof(FirstPage), typeof(FirstPage));
        Routing.RegisterRoute(nameof(SecondPage), typeof(SecondPage));
        Routing.RegisterRoute(nameof(ThirdPage), typeof(ThirdPage));
    }
    
    private async void MenuItem_OnClicked(object sender, EventArgs e)
    {
        var menuItem = sender as MenuItem;
        var classId = menuItem?.ClassId;
        switch (classId)
        {
            case null:
                return;
            case "FirstPage":
                await Current.GoToAsync("..", true);
                break;
            case "SecondPage":
                await Current.GoToAsync(nameof(SecondPage), true);
                break;
            case "ThirdPage":
                //...
        }
    }