maui
maui copied to clipboard
Make AppThemeBinding type public
Description
While working with C# Markup, the type AppThemeBinding is the equivalent of AppThemeBindingExtension from XAML.
But this type is marked as internal. So, unable to make use of it while defining theme-based Resource definition (as an instance assigned to the value of the Setter).
For inline View definition, there's an extension method available. But not for Setter as there's no instance associated to invoke the extension method. Refer to the intended use case for the sample.
Public API Changes
Make the AppThemeBinding type public.
https://github.com/dotnet/maui/blob/c3221bf08d291c9f69070aa11d6d60f61a569aae/src/Controls/src/Core/AppThemeBinding.cs#L9
Intended Use-Case
Allows resource reuse.
Resources.Add("MauiLabel", new Style(typeof(Label))
{
Setters =
{
new() { Property = Label.TextColorProperty, Value = new AppThemeBinding() { Dark = Colors.White, Light = Colors.Black } },
},
});
@brminnick C# markup does have access to internal methods, right? If so, can we create a Factory method for AppThemeBinding ? Or is there something already?
@brminnick C# markup does have access to internal methods, right? If so, can we create a Factory method for
AppThemeBinding? Or is there something already?
Yeah, it can even be in the Markup package as there's already an extension method available for AppThemeBinding (instance-based) but not for Setter. The return type has to be BindingBase and invoked directly.
We have extension methods, .AppThemeBinding() and .AppThemeColorBinding()
new Label()
.AppThemeBinding(Label.TextProperty, "Light Mode", "Dark Mode")
.AppThemeColorBinding(Label.TextColorProperty, Colors.Black, Colors.White);
var labelStyle = new Style<Label>()
.AddAppThemeBinding(Label.TextProperty, "Light Mode", "Dark Mode")
.AddAppThemeBinding(Label.TextColorProperty, Colors.Black, Colors.White);
new Label
{
Style = labelStyle
};
We have an extension method,
.AppThemeBinding()
Yes, but won't work in the context of Setter as there's no instance available to invoke this form of method. Style can be implicit also.
Maybe will try with the another version updated in the earlier comment.
@brminnick, it works seamlessly with the generic version Style<T>.
But one request, can another extension method be added to make it work with the non-generic version of Style to support the existing code base?
// Since Style is sealed, have defined as it is
public static Style AddAppThemeBinding(this Style style, BindableProperty property, object light, object dark)
{
// Issue is AppThemeBinding is inaccessible due to its protection level
style.Setters.Add(property, new AppThemeBinding() { Light = light, Dark = dark });
return style;
}
@brminnick Or to make it simple, add another constructor to generic Style<T> that takes a non-generic Style as a parameter. Any further operation after this is the same as working with that Style instance.
Since Style<T> can be implicitly converted to Style, the other way is not all an issue.
// Adding a condition to make it even more safer
public Style(Style style)
{
// Assign to the underlying property only if the Style's TargetType matches with that of the generic Type 'T'
if (typeof(T) == style.TargetType)
{
MauiStyle = style;
}
else
{
MauiStyle = new Style(typeof(T));
}
}
@egvijayanand I think that makes a lot of sense!
Check out the proposal I just opened and leave a comment with your thoughts! https://github.com/CommunityToolkit/Maui.Markup/issues/274
I found out that I can't access the AppThemeBinding. How do I make a multi-binding on text colour that also adapts to theme changes?
It makes no sense that MAUI exists, but you need to install a community library to be able to bind to the app theme changes at all. And the community library still does not expose the AppThemeBinding.
You might say: But I can already bind to the AppTheme in XAML. Exactly! Why is it publicly accessible in one language (XAML) but not in C#? It is extremely weird.