Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] StatusBarBehavior StatusBarColor DynamicResource binding not working #1056

Closed
2 tasks done
Cybrosys opened this issue Mar 1, 2023 · 10 comments
Closed
2 tasks done
Labels
bug Something isn't working

Comments

@Cybrosys
Copy link
Contributor

Cybrosys commented Mar 1, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Did you read the "Reporting a bug" section on Contributing file?

Current Behavior

I am trying to bind the StatusBarColor of StatusBarBehavior using a DynamicResource-binding, to support theming:

<ContentPage.Behaviors>
    <toolkit:StatusBarBehavior StatusBarColor="{DynamicResource Tertiary}" />
 </ContentPage.Behaviors>

This results in the StatusBarColor being white/transparent instead of the Tertiary color.

Using a StaticResource-binding works as expected.

I have only tested this on Android but @brminnick was able to reproduce it on iOS.

Expected Behavior

The status bar color should reflect the color referenced by the DynamicResource-binding.

Steps To Reproduce

  1. Open and run the sample on Android and iOS

Link to public reproduction project repository

https://github.com/Cybrosys/Sandbox/tree/master/MauiAppStatusBarColorDynamicResource

Environment

- .NET MAUI CommunityToolkit: 5.0.0
- OS: Android Emulator running Android 13.0 - API 33
- .NET MAUI: 7.0.59/7.0.100         VS 17.5.33424.131

Anything else?

No response

@Cybrosys Cybrosys added bug Something isn't working unverified labels Mar 1, 2023
@Cybrosys Cybrosys changed the title [BUG] [BUG] StatusBarBehavior StatusBarColor DynamicResource binding not working Mar 1, 2023
@Cybrosys
Copy link
Contributor Author

Cybrosys commented Mar 3, 2023

Out of curiosity, who would own the dynamic resource binding, the page or the behavior itself? Just to get a hint at where to begin looking/debugging this.

Could the issue I am experiencing be a core issue in MAUI related to bindings, behaviors and/or dynamic resources (there are issues reported related to DynamicResource in .NET 7 MAUI that people claim works in .NET 6)?

I did a test where I copied the StausBarBehavior code into my MainPage and in the ctor set the binding using the SetDynamicResource method:
SetDynamicResource(StatusBarColorProperty, "Tertiary");

This resulted in the expected behavior, but also negated the purpose of using Behaviors.

The method SetDynamicResource is exposed/made public on Element but appears to come from BindableObject. The method SetDynamicResource is not exposed through Behavior but Behavior does inherit from BindableObject.

Thus back to my original question and some more:

  • Who would "own" the binding?
    • Looks like each BindableObject would own their own bindings?
  • Who would create the binding when defined in XAML, is it the XAML parser?

If I put a breakpoint inside the StatusBarBehavior.StatusBarColorProperty (not the one I made), it is only accessed by itself in OnAttachedTo. So maybe this is a XAML parser issue and/or some check that says that this type of binding is not valid?

@pictos
Copy link
Member

pictos commented Mar 3, 2023

@Cybrosys the Behaviors, since XF, don't inherit the BindingContext of the AssociatedObject, so if you don't set that manually, the BindingContext will be null.

@Cybrosys
Copy link
Contributor Author

Cybrosys commented Mar 3, 2023

@Cybrosys the Behaviors, since XF, don't inherit the BindingContext of the AssociatedObject, so if you don't set that manually, the BindingContext will be null.

I have tried assigning a BindingContext to the StatusBarBehavior and that works for "normal" bindings "{Binding ...]" to a property on the owning ContentPage (view model binding, or what you want to call it). I have however not gotten the DynamicResource binding to work in the same way

@pictos
Copy link
Member

pictos commented Mar 3, 2023

@Cybrosys I've no clue if Behaviors do support DynamicResources... I would say they should, but I'm not sure. Maybe you can rise this question on Maui's repo.

@Cybrosys
Copy link
Contributor Author

Cybrosys commented Mar 4, 2023

Started a discussion in the main MAUI repo:
dotnet/maui#13691

@brminnick
Copy link
Collaborator

Behavior in .NET MAUI does not have support for ResourceDictionary and thus do not support StaticResource or DynamicResource

In .NET MAUI, Behavior inherits from BindableObject.

For a class to support ResourceDictionary, it needs to either inherit from VisualElement where public ResourceDictionary Resources { get; set; } exists, or implement IResourceProvider.

Closing because this is not a bug specific to the .NET MAUI Community Toolkit.

@brminnick brminnick closed this as not planned Won't fix, can't repro, duplicate, stale Mar 6, 2023
@Cybrosys
Copy link
Contributor Author

Cybrosys commented Mar 6, 2023

Thank you for the information @brminnick.

I would however like to mention that it does work with StaticResource:
image

StaticResourceExtension has quite a lot more code compared to DynamicResourceExtension where the static one has several fallbacks to resolving a value:
https://github.com/dotnet/maui/blob/main/src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs

https://github.com/dotnet/maui/blob/main/src/Controls/src/Xaml/MarkupExtensions/DynamicResourceExtension.cs

But, as you said, it is not an issue with MCT but rather with MAUI.

Going back to the mention that the solution is to implement IResourceProvider, would it really be just that simple? Well, it is not that simple since it is a private interface. I would guess that something also has to feed it a ResourceDictionary instance. Maybe the DynamicResourceExtension class would be the one to do that?

I would argue that you should be able to use DynamicResource even when not inheriting from VisualElement. The reason being that you can put any type of value into a ResourceDictionary, so in essence it is just a normal binding where the source is the parent or app's ResourceDictionary.

@pictos
Copy link
Member

pictos commented Mar 6, 2023

@Cybrosys I agree that would be a great addition, please open an issue on .NET MAUI repo asking for it

@Cybrosys
Copy link
Contributor Author

Cybrosys commented Mar 6, 2023

@Cybrosys I agree that would be a great addition, please open an issue on .NET MAUI repo asking for it

dotnet/maui#13724

@brminnick
Copy link
Collaborator

Thanks @Cybrosys!

I agree with @pictos. We get a lot of Issues opened here in the CommunityToolkit.Maui repo when things like DynamicResources and Bindings don't work as expected for Behaviors because of this.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants