dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.06k stars 1.73k forks source link

OnPlatform dynamic values not being utilized in controls #14575

Open williambohrmann3 opened 1 year ago

williambohrmann3 commented 1 year ago

Description

When using OnPlatform extension on a Label property, a dynamic value will not be utilized when running the app in Release mode. It will be utilized when running the app in Debug mode. The property in the provided repo is TextColor. The repo follows MVVM and sets the BindingContext in the code behind of MainPage. My Visual Studio environments are 17.5.4 on both Windows and Mac.

Steps to Reproduce

  1. Create a new .NET MAUI project
  2. Create a Color property in a new model class
  3. Have your model set the Color property to a color not white or black
  4. Set the BindingContext of MainPage to the model
  5. Add a Label in XAML; bind TextColor to your color property with OnPlatform extension (Default)
  6. Run app with Debug config; notice the binding is respected
  7. Run app with Release config; notice the binding is not respected

Link to public reproduction project repository

https://github.com/williambohrmann3/DynamicValuesBindingBug/tree/main/OnPlatformDynamicValuesBug

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android, Windows

Affected platform versions

minimums: Android 9, Windows SDK 10.0.19041.0, MacCatalyst 13.1, iOS 11

Did you find any workaround?

If you're able to hardcode your values, do that. If you're reliant on a property from code behind, unsure of a workaround.

Relevant log output

Microsoft.Maui.Controls.BindableObject: Warning: Cannot convert Microsoft.Maui.Controls.Binding to type 'Microsoft.Maui.Graphics.Color'
williambohrmann3 commented 1 year ago

In our production app, the IsVisible property of ImageButton was using the OnPlatform extension. On Default, we had a dynamic binding to a property in another class (MVVM). We actually ran into a InvalidCastException, only in Release mode. In debug config, the app was able to deploy just fine.

rachelkang commented 1 year ago

Related to https://github.com/dotnet/maui/issues/7664

ghost commented 1 year ago

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

PureWeen commented 1 year ago

@williambohrmann3 AFAIK AppThemeBinding doesn't support binding

You can only use StaticResources or values

ghost commented 1 year ago

Hi @williambohrmann3. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

williambohrmann3 commented 1 year ago

@PureWeen Good to know AppThemeBinding doesn't support binding. I've updated the issue title and description accordingly. Would be interested in learning more about XAML markup extension limitations.

I also updated my repo with more examples of controls. I am setting properties of my controls with an OnPlatform extension. The Default platforms have a binding to properties defined in my model. These properties are of type IList, double, bool, and Color. The binding context is set to the model in the code-behind of MainPage. All of my bindings are respected when in Debug:

WYeQyHS1Am

When in Release, my app will not deploy. I am getting a System.InvalidCastException: Unable to cast object of type Microsoft.Maui.Controls.Binding to type System.Boolean or double. When removing the CheckBox and Button controls (or to be more specific, the bindings) causing these exceptions, I am able to deploy in Release mode. However, it will not respect my Picker.ItemsSource and Label.TextColor OnPlatform bindings. Binding a property without using the OnPlatform extension will work.

pFD6AdTHlC

I also changed my bool and double to Boolean and Double to see if this was somehow related to my properties being primitive types. This is unrelated - changing from primitive types to objects does not resolve unhandled exceptions.

AnnYang01 commented 1 year ago

Verified this on Visual Studio Enterprise 17.7.0 Preview 2.0. Repro on Windows 11 with below Project, but not repro Android emulator (13.0-API 33). MauiApp15.zip screenshot in windows: image screenshot in Android, it can deploy in release config. image

MattePozzy commented 10 months ago

any solution? When I build the MAUI windows app in Relase it crashes with error like this: System.InvalidCastException: Unable to cast object of type 'Microsoft.Maui.Controls.Binding' to type 'System.Double'. when I use this instruction:

FontSize="{OnIdiom Desktop={Binding Source={x:Static lib:FontSize.Big}}, Phone={Binding Source={x:Static lib:FontSize.Large}}}"

With these seems to work:

Padding="{OnIdiom Phone=5}"
ColumnDefinitions="{OnPlatform WinUI='0.25*,*,0.25*', Android='*', iOS='*'}"
Grid.Column="{OnPlatform WinUI=1, Android=0, iOS=0}"
WidthRequest="{OnPlatform iOS=50, Android=50, WinUI=150}"
HeightRequest="{OnPlatform iOS=50, Android=50, WinUI=150}"
StrokeShape="{OnPlatform iOS='RoundRectangle 50,50,50,50', Android='RoundRectangle 50,50,50,50', WinUI='RoundRectangle 150,150,150,150'}"

we have an app in production environment that crashes because of this, where a fix will be released? Or there is a temporary workaround?

Net 8, visual studio 17.8.2

I have found a workaround. Create a style like this one and applies to components, seems to work:

<Style x:Key="PageTitleLabel" TargetType="Label">
    <Setter Property="HorizontalOptions" Value="Center" />
    <Setter Property="Padding" Value="{OnIdiom Phone=5}" />
    <Setter Property="FontSize" Value="{OnIdiom Desktop={Binding Source={x:Static lib:FontSize.Big}}, Phone={Binding Source={x:Static lib:FontSize.Large}}}" />
    <Setter Property="TextColor" Value="{AppThemeBinding Light={DynamicResource Primary}, Dark={DynamicResource PrimaryDark}}" />
</Style>
marossi7 commented 5 months ago

Any update on this ? I am facing the same issue.

DDHSchmidt commented 3 months ago

Thank you for the clever Style-workaround @MattePozzy 👍 This is one of the bugs that makes my QA guy come up to me and tell me I'm a haphazard, reckless cowboy-coder since he just clicks on a page and gets the app to crash and apparently I'm too lazy to even test that before I "dump my garbage on him" 😑

So yeah: +1 from me for this. Also: Why is only the platform/android Tag assigned? I can reproduce this across windows and iOS as well.