Reputation: 900
Why is the title bar changing colors and is there a workaround for this (presumable) bug?
To verify that this is can be reproduced I've created a new .NET MAUI project. I've added all the code of my fresh project below. It is a bit much but it's really just 3 pages, with buttons with a command that navigates using Shell
. Nothing special. Page A and B can both navigate to C. The only difference: A navigates to C using an absolute path /B/C, while B navigates to C directly (push on stack). So under any circumstance, going back from page C always ends up on B.
What happens is this:
B > C > (backto)B = title bar on B stays the same
A > B/C > (backto)B = title bar on B changes background color to dark gray, unintended
The title bar does change back to normal, after navigating away from the page and then going back again. The title bar color change is not permanent throughout the apps lifecycle.
Update
This bug has been reported at the .NET MAUI issues section on Github.
Preview
Using the Pixel 5 Android 13 API 33 emulator: In this example I am using the devices' back button, but the same happens when using an on-page <Button/>
in XAML with a command going back to page B instead. It makes no difference.
AppShell
<Shell
x:Class="TitleBarTest.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TitleBarTest"
Shell.FlyoutBehavior="Flyout">
<FlyoutItem Title="Title Bar Test">
<ShellContent ContentTemplate="{DataTemplate local:MainPage}"
Shell.FlyoutItemIsVisible="True"
Shell.TabBarIsVisible="True"
Title="Page A"
Route="MainPage"/>
<ShellContent ContentTemplate="{DataTemplate local:SecondPage}"
Shell.FlyoutItemIsVisible="True"
Shell.TabBarIsVisible="True"
Title="Page B"
Route="SecondPage"/>
</FlyoutItem>
<ShellContent ContentTemplate="{DataTemplate local:ModalPage}"
Shell.FlyoutItemIsVisible="False"
Shell.TabBarIsVisible="False"
Title="Page C"
Route="ModalPage"/>
</Shell>
Page A
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TitleBarTest"
x:DataType="local:MainPageViewModel"
x:Class="TitleBarTest.MainPage"
Title="Page A">
<VerticalStackLayout>
<Label
Text="List of A-items"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Button
Command="{Binding GoToModalViaSecondPageCommand}"
x:Name="CounterBtn"
Text="Go to C via B"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentPage>
ViewModel A:
public class MainPageViewModel : BaseViewModel
{
public Command GoToModalViaSecondPageCommand { get; private set; }
public MainPageViewModel()
{
GoToModalViaSecondPageCommand = new Command(GoToModalViaSecondPage);
}
public async void GoToModalViaSecondPage()
{
await Shell.Current.GoToAsync($"//{nameof(SecondPage)}/{nameof(ModalPage)}");
}
}
Page B
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TitleBarTest"
x:DataType="local:SecondPageViewModel"
x:Class="TitleBarTest.SecondPage"
Title="Page B">
<VerticalStackLayout>
<Label
Text="List of B-items"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Button
Command="{Binding GoToModalDirectlyCommand}"
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentPage>
ViewModel B:
public class SecondPageViewModel : BaseViewModel
{
public Command GoToModalDirectlyCommand { get; private set; }
public SecondPageViewModel()
{
GoToModalDirectlyCommand = new Command(GoToModalDirectly);
}
public async void GoToModalDirectly()
{
await Shell.Current.GoToAsync($"{nameof(ModalPage)}");
}
}
Page C
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TitleBarTest"
x:DataType="local:ModalPageViewModel"
x:Class="TitleBarTest.ModalPage"
Shell.PresentationMode="ModalAnimated"
BackgroundColor="#AA000000"
Title="Page C">
<StackLayout VerticalOptions="End">
<Frame BackgroundColor="White"
CornerRadius="24"
HeightRequest="256"
Margin="0,0,0,-24">
<VerticalStackLayout>
<Label
Text="Create new B-item"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</Frame>
</StackLayout>
</ContentPage>
ViewModel C:
public class ModalPageViewModel : BaseViewModel
{
public Command BackToPageBCommand { get; private set; }
public ModalPageViewModel()
{
BackToPageBCommand = new Command(BackToPageB);
}
public async void BackToPageB()
{
await Shell.Current.GoToAsync($"//{nameof(SecondPage)}");
}
}
Styles.xaml
In response to FreakyAlis' comment: The Shell.BackgroundColor
is defined in Styles.xaml by default and when I remove this, all title bars have this gray color. It seems like there is a "fall back" color defined somewhere. This is the default:
<Style TargetType="Shell" ApplyToDerivedTypes="True">
<Setter Property="Shell.BackgroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource Gray950}}" />
...
...
...
</Style>
Upvotes: 1
Views: 1087
Reputation: 900
It's not ideal, but popping to root first and then navigating to the desired page, did provide a workaround for this specific occasion.
Instead of only using await Shell.Current.GoToAsync($"//{nameof(DesiredPage)}", true);
I would pop to root first like this:
await Shell.Current.Navigation.PopToRootAsync(false);
await Shell.Current.GoToAsync($"//{nameof(DesiredPage)}", true);
And the title bar background color no longer changes for me. I've set the animation parameter to false
for PopToRootAsync(false)
Upvotes: 0