DynamicResource limitation for OnPlatform in XAML Xamarin.Forms?

AngeloIanCruzAngeloIanCruz USMember ✭✭
edited April 2016 in Xamarin.Forms

Hi All,
In our project, we were trying to use OnPlatform for the Background Color of a contentpage. So we tried using:
<ContentPage.BackgroundColor>

    <OnPlatform x:TypeArguments="Color" Android="{DynamicResource LightGrey}" iOS="White"/>

</ContentPage.BackgroundColor

What's weird is it was throwing an object reference not set because we were trying to use the DynamicResource. This dynamic resource is being used across the application, so it works. Moreover, when we tried changing to hex:

<ContentPage.BackgroundColor>
<OnPlatform x:TypeArguments="Color" Android="#807f7f7f"" iOS="White"/>
</ContentPage.BackgroundColor

or just a plain color like Gray or White, the exception goes away and everything works. Is this a known bug or limitation in the XAML?

Regards,
Angelo

Best Answer

  • NMackayNMackay GB mod
    edited April 2016 Accepted Answer

    @AngeloIanCruz

    yeah, it's an known limitation...and a pain. Hopefully it gets fixed sometime.

    Another way you could do it is to use an implicit style in your App.xaml.

    <Application
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="Foobar.App">
      <Application.Resources>
        <OnPlatform x:TypeArguments="ResourceDictionary">
          <OnPlatform.iOS>
            <ResourceDictionary>
              <Style x:Key="FieldLabelStyle" TargetType="Label">
                <Setter Property="TextColor" Value="#77787A" />
                <Setter Property="FontSize" Value="14" />
                <Setter Property="HorizontalOptions" Value="StartAndExpand" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="FontAttributes" Value="Bold" />
                <Setter Property="VerticalTextAlignment" Value="Center" />
                <Setter Property="LineBreakMode" Value="TailTruncation" />
                <Setter Property="BackgroundColor" Value="Transparent" />
              </Style>
            </ResourceDictionary>
          </OnPlatform.iOS>
          <OnPlatform.Android>
            <ResourceDictionary>
              <Style x:Key="FieldLabelStyle" TargetType="Label">
                <Setter Property="TextColor" Value="#77787A" />
                <Setter Property="FontSize" Value="16" />
                <Setter Property="HorizontalOptions" Value="StartAndExpand" />
                <Setter Property="VerticalOptions" Value="FillAndExpand" />
                <Setter Property="FontAttributes" Value="Bold" />
                <Setter Property="VerticalTextAlignment" Value="Center" />
                <Setter Property="LineBreakMode" Value="TailTruncation" />
                <Setter Property="BackgroundColor" Value="Transparent" />
              </Style>
            </ResourceDictionary>
          </OnPlatform.Android>
        </OnPlatform>
      </Application.Resources>
    </Application>
    

    And then assign the style to the control.

    <Label Grid.Row="0"
                         Grid.Column="0"
                         Text="Label with implicit style"
                         Style="{StaticResource FieldLabelStyle}" />
    

Answers

  • NMackayNMackay GBInsider, University mod
    edited April 2016 Accepted Answer

    @AngeloIanCruz

    yeah, it's an known limitation...and a pain. Hopefully it gets fixed sometime.

    Another way you could do it is to use an implicit style in your App.xaml.

    <Application
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="Foobar.App">
      <Application.Resources>
        <OnPlatform x:TypeArguments="ResourceDictionary">
          <OnPlatform.iOS>
            <ResourceDictionary>
              <Style x:Key="FieldLabelStyle" TargetType="Label">
                <Setter Property="TextColor" Value="#77787A" />
                <Setter Property="FontSize" Value="14" />
                <Setter Property="HorizontalOptions" Value="StartAndExpand" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="FontAttributes" Value="Bold" />
                <Setter Property="VerticalTextAlignment" Value="Center" />
                <Setter Property="LineBreakMode" Value="TailTruncation" />
                <Setter Property="BackgroundColor" Value="Transparent" />
              </Style>
            </ResourceDictionary>
          </OnPlatform.iOS>
          <OnPlatform.Android>
            <ResourceDictionary>
              <Style x:Key="FieldLabelStyle" TargetType="Label">
                <Setter Property="TextColor" Value="#77787A" />
                <Setter Property="FontSize" Value="16" />
                <Setter Property="HorizontalOptions" Value="StartAndExpand" />
                <Setter Property="VerticalOptions" Value="FillAndExpand" />
                <Setter Property="FontAttributes" Value="Bold" />
                <Setter Property="VerticalTextAlignment" Value="Center" />
                <Setter Property="LineBreakMode" Value="TailTruncation" />
                <Setter Property="BackgroundColor" Value="Transparent" />
              </Style>
            </ResourceDictionary>
          </OnPlatform.Android>
        </OnPlatform>
      </Application.Resources>
    </Application>
    

    And then assign the style to the control.

    <Label Grid.Row="0"
                         Grid.Column="0"
                         Text="Label with implicit style"
                         Style="{StaticResource FieldLabelStyle}" />
    
  • AngeloIanCruzAngeloIanCruz USMember ✭✭

    @NMackay said:
    @AngeloIanCruz

    yeah, it's an known limitation...and a pain. Hopefully it gets fixed sometime.

    Another way you could do it is to use an implicit style in your App.xaml.

    <Application
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="Foobar.App">
      <Application.Resources>
        <OnPlatform x:TypeArguments="ResourceDictionary">
          <OnPlatform.iOS>
            <ResourceDictionary>
              <Style x:Key="FieldLabelStyle" TargetType="Label">
                <Setter Property="TextColor" Value="#77787A" />
                <Setter Property="FontSize" Value="14" />
                <Setter Property="HorizontalOptions" Value="StartAndExpand" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="FontAttributes" Value="Bold" />
                <Setter Property="VerticalTextAlignment" Value="Center" />
                <Setter Property="LineBreakMode" Value="TailTruncation" />
                <Setter Property="BackgroundColor" Value="Transparent" />
              </Style>
            </ResourceDictionary>
          </OnPlatform.iOS>
          <OnPlatform.Android>
            <ResourceDictionary>
              <Style x:Key="FieldLabelStyle" TargetType="Label">
                <Setter Property="TextColor" Value="#77787A" />
                <Setter Property="FontSize" Value="16" />
                <Setter Property="HorizontalOptions" Value="StartAndExpand" />
                <Setter Property="VerticalOptions" Value="FillAndExpand" />
                <Setter Property="FontAttributes" Value="Bold" />
                <Setter Property="VerticalTextAlignment" Value="Center" />
                <Setter Property="LineBreakMode" Value="TailTruncation" />
                <Setter Property="BackgroundColor" Value="Transparent" />
              </Style>
            </ResourceDictionary>
          </OnPlatform.Android>
        </OnPlatform>
      </Application.Resources>
    </Application>
    

    And then assign the style to the control.

    <Label Grid.Row="0"
                         Grid.Column="0"
                         Text="Label with implicit style"
                         Style="{StaticResource FieldLabelStyle}" />
    

    Thanks for the response Mr. NMackay! :)

  • PeterMurphyPeterMurphy USMember ✭✭

    @NMackay Is this problem limited to the use of OnPlatform or is it also true of resources in general?

    For example, I have this scenario:

    XAML:

        <Color x:Key="LabelTextColor">#FF00244D</Color>
    
        <Style x:Key="TemplateViewCellLabel" TargetType="Label">
            <Setter Property="TextColor" Value="{DynamicResource LabelTextColor}"/>
        </Style>
    

    Code:

        var itemText = new Label
        {
            Style = _resourceManager.GetStyleObject<Style>("TemplateViewCellLabel", null)
        };
    

    (_resourceManager is custom code that returns the Style object).

    In the code above, the TextColor is not picked up as a DynamicResource, but instead displays the default color. It only works if I change the XAML to:

        <Style x:Key="TemplateViewCellLabel" TargetType="Label">
            <Setter Property="TextColor" Value="#FF00244D"/>
        </Style>
    

    Is this the same bug? Or am I doing something wrong?

    Thanks in advance,

    Peter.

  • AngeloIanCruzAngeloIanCruz USMember ✭✭
    edited July 2016

    @PeterMurphy said:
    @NMackay Is this problem limited to the use of OnPlatform or is it also true of resources in general?

    For example, I have this scenario:

    XAML:

    #FF00244D



    Code:

        var itemText = new Label
        {
            Style = _resourceManager.GetStyleObject<Style>("TemplateViewCellLabel", null)
        };
    

    (_resourceManager is custom code that returns the Style object).

    In the code above, the TextColor is not picked up as a DynamicResource, but instead displays the default color. It only works if I change the XAML to:

        <Style x:Key="TemplateViewCellLabel" TargetType="Label">
            <Setter Property="TextColor" Value="#FF00244D"/>
        </Style>
    

    Is this the same bug? Or am I doing something wrong?

    Thanks in advance,

    Peter.

    @PeterMurphy I don't think this is the same bug. This type of code works perfectly in our project. For example:

                        <Color x:Key="Green">#27B034</Color>
            <Style TargetType="Label">
                <Setter Property="TextColor" Value="{DynamicResource Green}" />
            </Style>
    

    The difference I noticed in your code is that the value of your color is 8 digits while we use 6 hexadecimal digits. This might be causing the problem on your end.

    Regards,
    Angelo

  • PeterMurphyPeterMurphy USMember ✭✭

    @AngeloIanCruz Thanks for your reply.

    I've tried using a 6-character hex string but with no success. I have a feeling this might be down to us not using an App.xaml file in our application (our views are built entirely in code).

    Peter.

  • PeterMurphyPeterMurphy USMember ✭✭

    In my case, changing to StaticResource has worked.

  • JKayJKay USMember ✭✭✭

    Has anyone filed a Bugzilla for this? Is this a bug or a limitation?

  • DerProgrammiererDerProgrammierer DEMember ✭✭✭
    edited October 2016

    +1

    @PeterMurphy: StaticResource is working for UWP (WinPhone) for me, but Android is only working with DynamicResource.

    @NMackay the workaround you posted seems legit but is not working for me because of the reason explained above.

    This is basically what I'm trying to achive:

    <Label.TextColor> <OnPlatform x:Key="RightBubbleFontColor" x:TypeArguments="Color" iOS="{DynamicResource rightBubbleFontColor}" Android="{DynamicResource rightBubbleFontColor}" WinPhone="{StaticResource rightBubbleFontColor}"> </OnPlatform> </Label.TextColor>

    It's still not working for now. I also asked a question about this on Stackoverflow:
    http://stackoverflow.com/questions/39852888/xamarin-forms-use-dynamicresource-or-staticresource-depending-on-os

  • NMackayNMackay GBInsider, University mod

    @DerProgrammierer

    From a brief chat with @StephaneDelcroix on the 2.3.3 pre2 release notes thread he seemed to suggest staticresources and onplatform will be fixed in 2.3.4 or 2.3.3 pre3 so keep a close eye on the release notes when the next version it out.

    https://forums.xamarin.com/discussion/77854/xamarin-forms-2-3-3-pre2/p1

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    @NMackay I indeed lately fixed a problem related to OnPlatform, OnIdiom and StaticResources with XamlC on. Is there any other problem with XamlC off that I should be aware ?

  • NMackayNMackay GBInsider, University mod
    edited October 2016

    @StephaneDelcroix

    Not that I'm aware of. I was just referring to the example of @DerProgrammierer above as I thought this fix would resolve his issue in a future release. Will the static resource fix make it into 2.3.3 stable?

    Thanks for responding :smile:

  • NMackayNMackay GBInsider, University mod

    Awesome.

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭
    edited October 2016

    @DerProgrammierer that won't work. Your OnPlatform is of Type Color. Using the StaticResource will probably get you the right Color, but DynamicResource is very much like a Binding and only applicable to BindableProperties.

    Have you reported the issue about StaticResource not working on Android (it should work)

  • DerProgrammiererDerProgrammierer DEMember ✭✭✭

    @StephaneDelcroix said:
    @DerProgrammierer that won't work. Your OnPlatform is of Type Color. Using the StaticResource will probably get you the right Color, but DynamicResource is very much like a Binding and only applicable to BindableProperties.

    Have you reported the issue about StaticResource not working on Android (it should work)

    Thank you for your response. Actually one of my coworkers is responsible for all Android code and she told me that she tested it and it didn't work with StaticResource on Android. Tomorrow I will ask her again and test it together with her and then come back here to say what happened.

    By the way, where can I report an issue?

  • DerProgrammiererDerProgrammierer DEMember ✭✭✭

    We were able to solve it.

    RightViewCell.xaml:
    <Label Style="{StaticResource labelStyle}" HorizontalTextAlignment="End" Text="{Binding message}" TextColor="{StaticResource rightBubbleFontColor}"> </Label>

    App.xaml:
    <Style x:Key="labelStyle" TargetType="Label"> <Setter Property="TextColor" Value="{DynamicResource labelFontColor}" /> <Setter Property="FontFamily" Value="{DynamicResource globalFont}" /> <Setter Property="FontSize" Value="14" /> </Style>

    The problem was that the Label Style was a StaticResource so after the binding to the style happened, we were not able to change the color anymore.

    What I don't understand tho is that the above code was used for iOS, Android and UWP. But with this specific code you can see above, the color only applied on UWP, not on iOS and Android.

  • KatoMarkhusKatoMarkhus USMember ✭✭
    edited October 2016

    Had an issue with resourse files from my pcl not working on UWP project - after upraging my PCL to opt into NuGet 3.0 support - my resource files worked as they schould. How to is seen in the begining of setup in this article; https://github.com/microsoftgraph/xamarin-csharp-connect-sample/wiki/Set-up-a-Xamarin-Forms-project-to-use-the-MSAL-.NET-SDK

Sign In or Register to comment.