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

Steven Manuel 21 Reputation points
2021-05-31T04:54:05.73+00:00

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

Developer technologies .NET Xamarin
{count} votes

Accepted answer
  1. Kyle Wang 5,531 Reputation points Microsoft External Staff
    2021-06-01T07:14:59.27+00:00

    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.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.