How to use OnIdiom to reference OnPlatform data in XAML?

FrankieFooFrankieFoo MYUniversity ✭✭
edited September 2016 in Xamarin.Forms

I'm trying to set different text size, for each different platform & form factor in the application wide ResourceDictionary

<OnPlatform x:Key="myfontsize-phone" x:TypeArguments="x:Double" iOS="20" Android="20" WinPhone="30"/> <OnPlatform x:Key="myfontsize-tablet" x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="60"/> ... <OnIdiom x:Key="myfontsize" x:TypeArguments="x:Double" Phone="{StaticResource myfontsize-phone}" Tablet="{StaticResource myfontsize-tablet}"/>

and in my page XAML, i just call it with

<Label Text="SomeText" FontSize="{StaticResource myfontsize}"/>

The code above compile alright, but on run time I encountered with "System.InvalidCastException: Specified cast is not valid" in my page's InitializeComponent(). If I take out the reference to the and reference to the item instead, it will work alright.

This is what I get in the debug log, which isn't much help
09-01 20:56:01.292 E/mono (15401): Unhandled Exception: 09-01 20:56:01.292 E/mono (15401): System.InvalidCastException: Specified cast is not valid. 09-01 20:56:01.292 E/mono (15401): at (wrapper dynamic-method) System.Object:be601f56-8ff2-4aab-a41a-aababab502f5 (intptr,intptr,intptr) 09-01 20:56:01.292 E/mono (15401): at (wrapper native-to-managed) System.Object:be601f56-8ff2-4aab-a41a-aababab502f5 (intptr,intptr,intptr) 09-01 20:56:01.294 E/mono-rt (15401): [ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidCastException: Specified cast is not valid. 09-01 20:56:01.294 E/mono-rt (15401): at (wrapper dynamic-method) System.Object:be601f56-8ff2-4aab-a41a-aababab502f5 (intptr,intptr,intptr) 09-01 20:56:01.294 E/mono-rt (15401): at (wrapper native-to-managed) System.Object:be601f56-8ff2-4aab-a41a-aababab502f5 (intptr,intptr,intptr)

Any clue on what might have gone wrong?

Answers

  • NMackayNMackay GBInsider, University mod
    edited September 2016

    @FrankieFoo

    Good question, I has this on my list to look into. I tried your approach and various others and got compilation errors or nothing worked or the XamlC compiler threw an error when building the dictionary/page. The only way I could get it to work was like this..

    <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 TargetType="Label" x:Key="myfontsize">
                <Setter Property="FontSize">
                  <OnIdiom x:TypeArguments="x:Double" Phone="20" Tablet="40" />
                </Setter>
              </Style>
            </ResourceDictionary>
          </OnPlatform.iOS>
          <OnPlatform.Android>
            <ResourceDictionary>
              <Style TargetType="Label" x:Key="myfontsize">
                <Setter Property="FontSize">
                  <OnIdiom x:TypeArguments="x:Double" Phone="20" Tablet="40" />
                </Setter>
              </Style>
            </ResourceDictionary>
          </OnPlatform.Android>
          <OnPlatform.WinPhone>
            <ResourceDictionary>
              <Style TargetType="Label" x:Key="myfontsize">
                <Setter Property="FontSize">
                  <OnIdiom x:TypeArguments="x:Double" Phone="30" Tablet="60" />
                </Setter>
              </Style>
            </ResourceDictionary>
          </OnPlatform.WinPhone>
        </OnPlatform>
      </Application.Resources>
    </Application>
    

    And set the label

       <Label Text="{Binding DisplayName}" TextColor="#595959" Style="{StaticResource myfontsize}"
                             HorizontalOptions="Center" VerticalOptions="Center" />
    

    If you can get your approach working then let me know, I can probably live with the approach I've shown above.

  • FrankieFooFrankieFoo MYUniversity ✭✭
    edited September 2016

    @NMackay

    I will try your approach, and see how it goes.

    Anyway, I've got the code below to compile, and no error raised at runtime by changing from StaticResource to DynamicResource at the UI XAML code.

    <OnPlatform x:Key="mycolor-phone" x:TypeArguments="Color" iOS="Red" Android="Yellow" WinPhone="Blue"/> <OnPlatform x:Key="mycolor-tablet" x:TypeArguments="Color" iOS="Silver" Android="Olive" WinPhone="Purple"/> <OnIdiom x:Key="mycolor" x:TypeArguments="Color" Phone="{StaticResource mycolor-phone}" Tablet="{StaticResource mycolor-tablet}"/> ... <BoxView BackgroundColor="{DynamicResource mycolor}"/>

    The code detected the platform alright, but the form factor isn't. It always defaulted to phone.

  • NMackayNMackay GBInsider, University mod
    edited September 2016

    @FrankieFoo

    Thanks for updating the thread. Did the code I posted not work out of interest? it detected tablet or handset okay for me.

  • FrankieFooFrankieFoo MYUniversity ✭✭
    edited September 2016

    @NMackay

    I actually haven't have chances to try out your code yet,. It's 3AM late here in South-east Asia, so today is not the time. Will keep you updated with the result within the next day or two.

  • cybernavidcybernavid USMember ✭✭

    @NMackay thnx a bunch for your XAML OnPlatform and OnIdiom code, as I miss those in Xamarin documentation online.

  • KuhdinkleKuhdinkle USMember ✭✭

    Another option is :

    in ResourceDictionary



    and for a Label

    FontSize="{StaticResource fontSize}"

  • KuhdinkleKuhdinkle USMember ✭✭

    that is

    Another option is:

    in ResourceDictionary

    and for a Label

    FontSize="{StaticResource fontSize}"

  • KuhdinkleKuhdinkle USMember ✭✭

    @FrankieFoo

    in ResourceDictionary



    and for Label

    FontSize="{StaticResource fontSize}"

Sign In or Register to comment.