CarlJ
CarlJ

Reputation: 153

.NET Maui - option to neuter property binding

In .NET Maui I have this XAML:

        <Style x:Key="GreenLabelStyle" TargetType="Label">
            <Setter Property="TextColor" Value="Green"/>                      
        </Style>              

       <Label Style="{StaticResource GreenLabelStyle}" 
              Text="Some text"
              TextColor="{Binding SometimesOverrideColor}"
              />

       <CheckBox IsChecked="{Binding OverrideColorStyle}"/>

The Label's TextColor is bound to this property:

    public Color SometimesOverrideColor
    {
        get
        {
            return OverrideColorStyle ? Colors.Pink : Colors.Green; // works, but not DRY
        }
    }

Even though I have a specified a (bound) TextColor, I want the option to say "ignore this property setting and act as though there were no explicit TextColor on the Label". I tried returning null for SometimesOverrideColor, but that didn't work. I want to use the value of the Label's style (i.e. green).

Obviously, I can return Colors.Green in SometimesOverrideColor, but that repeats the value specified in the style. If I changed the style I would have to remember to update the property.

What I have in mind is like the inherit keyword in CSS. If I could return Color.Inherit that would be great!

Upvotes: 0

Views: 173

Answers (2)

H.A.H.
H.A.H.

Reputation: 3907

I do not know how familiar you are with behaviors.

If you take for example CommunityToolkit.Maui, and check out ValidationBehavior.

You have two styles: ValidVisualState and InvalidVisualState.

Now, this behavior revolves around one boolean - IsValid. That boolean gets changed based on different sub-classes. (You can for example validate text using regex.)

Anyway, the interesting points there are two methods: UpdateStyle and UpdateSate.

And you then have

VisualStateManager.GoToState(view, isValid ? ValidVisualState : InvalidVisualState);

It doesn't have to be a bool, you know.

You can have behavior, using Style1, Style2, Style3... And so on. And then one bound variable that plays the role of "switch".

And because it is a "style", you can change all kinds of properties, not specifically the color.

Check this link: https://learn.microsoft.com/en-us/dotnet/communitytoolkit/maui/behaviors/

And if nothing works out of the box, you can "get inspiration" to make your own behavior. (Notice how I did not say steal. Stealing is wrong)

Upvotes: 0

FreakyAli
FreakyAli

Reputation: 16547

Based on my understanding of your question I would do something to the effect of this

 <Style TargetType="Label">
        <Setter Property="TextColor" Value="Black" />
        <Setter Property="FontFamily" Value="OpenSansRegular" />
        <Setter Property="FontSize" Value="14" />
    </Style>

    <Style x:Key="SometimesOverrideColor" TargetType="Label">
        <Setter Property="TextColor" Value="Pink" />
    </Style>

    <Style x:Key="GreenLabelStyle" TargetType="Label">
        <Setter Property="TextColor" Value="Green" />
    </Style>

And then write a short converter that would conditionally apply this:


//Name this sensibly 
public abstract class WhateverColorConveter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is not bool condition)
        {
            return null; // in case someone uses the converter but is a smartass
        }

        return  Application.Current.Resources.GetResource<Style>(condition ? "SometimesOverrideColor" : "GreenLabelStyle");
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

GetResource is an extension I have created:

 public static T GetResource<T>(this ResourceDictionary dictionary, string key)
    {
        if (dictionary.TryGetValue(key, out var value) && value is T resource)
            return resource;
        else
            return default;
    }

And then this would be used with your XAML code style, don't forget to add this into your resources as a static resource:


<ContentPage.Resources>
    <converters:WhateverColorConveter x:Key="WhateverColorConverter" />
</ContentPage.Resources>

And then use this :

<Label Style={Binding Condition, Converter={StaticResource WhateverColorConverter}}/>

Upvotes: 0

Related Questions