question

StevenManuel-7797 avatar image
0 Votes"
StevenManuel-7797 asked StevenManuel-7797 commented

Xamarin Forms Shell nav bar back button and toolbar button not visible after applying styling programmatically

I'm using Shell and I can change the nav bar color to yellow, which works well also when navigating.

Like this:
100955-image.png
100956-image.png

That's achieved using the following style:
<Shell.Resources>
<ResourceDictionary>
<Style x:Key="BaseStyle" TargetType="Element">
<Setter Property="Shell.BackgroundColor" Value="White" />
<Setter Property="Shell.ForegroundColor" Value="{StaticResource ONRSRYellow}" />
<Setter Property="Shell.TitleColor" Value="{StaticResource ONRSRDarkGrey}" />
<Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
<Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
<Setter Property="Shell.TabBarBackgroundColor" Value="White" />
<Setter Property="Shell.TabBarForegroundColor" Value="Black"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="{StaticResource ONRSRDarkGrey}"/>
<Setter Property="Shell.TabBarTitleColor" Value="Black"/>
</Style>
<Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
</ResourceDictionary>
</Shell.Resources>

Sometimes I have to replace the shell content with a "service not available" page, and then bring up the original content back once service is available again. I use the method suggested here: https://forums.xamarin.com/discussion/181459/how-to-change-shellcontent-contenttemplate-from-code-behind.

Basically something like this:

 if (!serviceAvailable) {
     // replace with service not available page
     ((AppShell)Shell.Current).ReportsTab.Items[0] = new ShellContent { Content = new NoConnectivityPage()};
 }
 else {
     // restore the reports page
     var newshellcontent= new ShellContent { Content = new ReportsPage()};
     ((AppShell)Shell.Current).ReportsTab.Items[0] = newshellcontent;
 }

The problem is upon displaying the original content, the style is also reset and the above style is no longer applied.

The best I've achieved is the reports page nav bar background is now yellow, but once navigating the back button and toolbar button are also yellow therefore not visible.

 Shell.SetForegroundColor(((AppShell)Shell.Current).ReportsTab, (Color)Application.Current.Resources["ONRSRYellow"]);

100957-image.png

How can I fix this so the back button and toolbar button are white? What am I missing?

Thanks in advance
Steven


dotnet-xamarin
image.png (4.9 KiB)
image.png (6.7 KiB)
image.png (6.0 KiB)
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@StevenManuel-7797 Base on your description, I could not reproduce the problem you encountered. It would be better if you can provide a simple demo via OneDrive or Github.

0 Votes 0 ·

1 Answer

KyleWang-MSFT avatar image
0 Votes"
KyleWang-MSFT answered StevenManuel-7797 commented

Hi StevenManuel-7797,

Welcome to our Microsoft Q&A platform!

To show a error page while the service is not available, you don't need to create an extra Page "NoConnectivityPage".

Here is a workaround you can refer to.

Just define a Grid in your ReportsPage and create two StackLayout to show "Report" and "NoConnectivity". In this way, you only need to set the "IsVisible" property to switch the page.

 <ContentPage.Content>
     <Grid>
         <StackLayout IsVisible="{Binding IsConnected}">
             <Label Text="Report Page"
                     FontSize="50"/>
         </StackLayout>
    
         <StackLayout IsVisible="{Binding ShowErrorView}">
             <Label Text="Error Page"
                     FontSize="50"/>
         </StackLayout>
     </Grid>
 </ContentPage.Content>

Here is a simple demo that suppose an error page will be displayed when there is no network

 class ReportViewModel : INotifyPropertyChanged
 {
     private bool isConnected;
     public bool IsConnected
     {
         get => isConnected;
         set
         {
             isConnected = value;
             OnPropertyChanged("IsConnected");
         }
     }
    
     private bool showErrorView;
     public bool ShowErrorView
     {
         get => showErrorView;
         set
         {
             showErrorView = value;
             OnPropertyChanged("ShowErrorView");
         }
     }
     public ReportViewModel()
     {
         IsConnected = true;
         ShowErrorView = false;
         CheckNetworkOnStart();
         CheckNetwork();
     }
    
     public void CheckNetworkOnStart()
     {
         if (Connectivity.NetworkAccess == NetworkAccess.Internet)
         {
             IsConnected = true;
         }
         else
         {
             IsConnected = false;
         }
         ShowErrorView = !IsConnected;
     }
    
     public void CheckNetwork()
     {
         Connectivity.ConnectivityChanged += (sender, args) =>
         {
             if (Connectivity.NetworkAccess == NetworkAccess.Internet)
             {
                 IsConnected = true;
             }
             else
             {
                 IsConnected = false;
             }
             ShowErrorView = !IsConnected;
         };
     }
    
     public event PropertyChangedEventHandler PropertyChanged;
    
     protected void OnPropertyChanged(string propertyName)
     {
         var handler = PropertyChanged;
         if (handler != null)
             handler(this, new PropertyChangedEventArgs(propertyName));
     }
 }

Code to open "ReportsPage".

 Shell.Current.GoToAsync($"{nameof(ReportsPage)}");

Regards,
Kyle


If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks Kyle. I have implemented what you suggested and it works great.

0 Votes 0 ·