Reputation: 153
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
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
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