.netxamldata-bindingmauidatatrigger

.NET MAUI Way to reuse constantly reused XAML Triggers?


Pretty new to MAUI dev. I have a situation in my MAUI app, where I need to change the text color of MANY labels based on a bool. So if the bool is true I want many of the labels to switch from white to grey color.

Currently, my solution is super repetitive. I want a simple thing that shows something like 1 / 4, where 1 and 4 are two variables. Maybe I'm approaching this completely wrong, but I haven't figured out any way to reduce this insanely long XAML code, to do something that I thing is super simple.

I just want those 3 characters to change colours when a bool flips! Keep in mind I need this type of color swap in many places throughout the app.

            <Label Text="{Binding SomeNumber}">
                <Label.Triggers>
                    <DataTrigger TargetType="Label"
                             Binding="{Binding SomeTriggerBool}"
                             Value="True">
                        <Setter Property="TextColor" Value="Grey" />
                    </DataTrigger>
                </Label.Triggers>
            </Label>
            <Label Text="/">
                <Label.Triggers>
                    <DataTrigger TargetType="Label"
                                 Binding="{Binding SomeTriggerBool}"
                                 Value="True">
                        <Setter Property="TextColor" Value="Grey" />
                    </DataTrigger>
                </Label.Triggers>
            </Label>
            <Label Text="{Binding SomeOtherNumber}">
                <Label.Triggers>
                    <DataTrigger TargetType="Label"
                                 Binding="{Binding SomeTriggerBool}"
                                 Value="True">
                        <Setter Property="TextColor" Value="Grey" />
                    </DataTrigger>
                </Label.Triggers>
            </Label>

Any way to go about this differently? Or at the very least reuse the trigger code? Without the triggers it looks like this:

            <Label Text="{Binding SomeNumber}" />
            <Label Text="/" />
            <Label Text="{Binding SomeOtherNumber}" />

This just screams to me that I'm doing something wrong.


Solution

  • I think in your case better to use Converter instead of triggers.

    Example: Define a class like below

    public class BoolToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if(value is bool isTrue)
            return isTrue ? Colors.Grey : Colors.White;
            return Colors.White;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    Then add the converter to App.xaml so that you can use this anywhere in the app

     <local:BoolToColorConverter x:Key="BoolToColorConverter" />
    

    You can use Converter like this

     <Label Text="{Binding SomeNumber}" TextColor="{Binding SomeTriggerBool, Converter={StaticResource BoolToColorConverter}}" />
        <Label Text="/" TextColor="{Binding SomeTriggerBool, Converter={StaticResource BoolToColorConverter}}" />
        <Label Text="{Binding SomeOtherNumber}" TextColor="{Binding SomeTriggerBool, Converter={StaticResource BoolToColorConverter}}" />
    

    know more here