Search code examples
convertersmauimaui-community-toolkit

MAUI How to bind Shell BackgroundColor by boolean variable to StaticResource color?


I will bind StaticResource colors as BackgroundColor to the Shell (at AppShell.xaml) by a boolean variable. My solution does not work. I get always the default BackgroundColor (see Style on the bottom). I get never the Yellow100 or Gray500. Where ist the mistake?

<Shell ...  
    xmlns:viewModels="clr-namespace:MyApp.ViewModels"
    x:DataType="viewModels:AppShellViewModel"
    BackgroundColor="{Binding IsOnline, Converter={StaticResource BoolToColorConverter}}" >

    <Shell.Resources>
        <ResourceDictionary>
            <toolkit:IsStringNotNullOrEmptyConverter x:Key="IsStringNotNullOrEmptyConverter" />
            <toolkit:BoolToObjectConverter x:Key="BoolToColorConverter" TrueObject="{StaticResource Yellow100}" FalseObject="{StaticResource Gray500}" />
        </ResourceDictionary>
    </Shell.Resources>

I tried also using x:TypeArguments="Color" or x:DataType="Color"

My ViewModel:

public partial class AppShellViewModel : ObservableObject
{
    [ObservableProperty]
    private bool _isOnline;

    public AppShellViewModel(ConnectionStateService connectionStateService)
    {
        IsOnline = connectionStateService.IsOnline();
    }
}

My Colors.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

    <Color x:Key="Gray500">#6E6E6E</Color>
    <Color x:Key="Yellow100">#F7B548</Color>

I tried this and this works fine:

BackgroundColor="{StaticResource Yellow100Accent}"

A default color ist set via Style at Styles.xaml:

<Style TargetType="Shell" ApplyToDerivedTypes="True">
    <Setter Property="Shell.BackgroundColor"
            Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource Gray950}}" /> ...

AppShell.xaml.cs:

public partial class AppShell
{
    private readonly AppShellViewModel _appShellViewModel;

    public AppShell(AppShellViewModel appShellAppShellViewModel)
    {
        _appShellViewModel = appShellAppShellViewModel;

        BindingContext = _appShellViewModel;

        InitializeComponent();

        Routing.RegisterRoute(nameof(FirstPage), typeof(FirstPage));
        Routing.RegisterRoute(
    ...
    } ....

Solution

  • The datatrigger may be a better choice:

    <Shell.Triggers>
            <DataTrigger TargetType="Shell" Binding="{Binding IsOnline}" Value="True">
                <Setter Property="BackgroundColor" Value="{StaticResource Yellow100Accent}"/>
            </DataTrigger>
            <DataTrigger  TargetType="Shell" Binding="{Binding IsOnline}" Value="False">
                <Setter Property="BackgroundColor" Value="{StaticResource Blue100Accent}"/>
            </DataTrigger>
        </Shell.Triggers>