Emixam23
Emixam23

Reputation: 3964

StaticResource into MarkupExtension

I'm currently trying to use a static resource with an extension for my entry's FontSize property. I have this code piece of code:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="PROJECT.Sources.Pages.Extras.EditProfilePage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:control="clr-namespace:PROJECT.Sources.Controls;assembly=PROJECT"
    xmlns:extension="clr-namespace:PROJECT.Sources.Extensions;assembly=PROJECT"
    xmlns:sys="clr-namespace:System;assembly=mscorlib">

    <ContentPage.Resources>
        <ResourceDictionary>
            <Color x:Key="NL_BlueNight">#0E1728</Color>
            <Color x:Key="NL_OrangeBeer">#E87E07</Color>
            <Color x:Key="NL_OrangeSky">#BD4327</Color>
            <Color x:Key="NL_White">#ECECEC</Color>
            <sys:Double x:Key="EntryFontSize">20</sys:Double>
        </ResourceDictionary>
    </ContentPage.Resources>

    <ContentPage.Content>
        <AbsoluteLayout BackgroundColor="{x:StaticResource NL_BlueNight}">
            <AbsoluteLayout
                Margin="{Binding LayoutThicknessAdapter}"
                AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                AbsoluteLayout.LayoutFlags="All"
                BackgroundColor="Black">
                <control:Gif
                    AbsoluteLayout.LayoutBounds="0.5, 0, 1, 0.9"
                    AbsoluteLayout.LayoutFlags="All"
                    GifSource="Gifs/LoginBackground.gif" />
                <BoxView
                    AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                    AbsoluteLayout.LayoutFlags="All"
                    BackgroundColor="Transparent" />
            </AbsoluteLayout>

            <AbsoluteLayout
                Margin="{Binding LayoutThicknessAdapter}"
                AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                AbsoluteLayout.LayoutFlags="All"
                BackgroundColor="{StaticResource NL_BlueNight}"
                Opacity="0.8">
                <ScrollView AbsoluteLayout.LayoutBounds="0.5, 0, 1, 0.9" AbsoluteLayout.LayoutFlags="All">
                    <StackLayout
                        HorizontalOptions="Fill"
                        Orientation="Vertical"
                        Spacing="15"
                        VerticalOptions="CenterAndExpand">
                        <BoxView BackgroundColor="Transparent" HeightRequest="{Binding SeparatorHeight}" />
                        <control:CustomImageCircle
                            x:Name="UserProfileImageButton"
                            HeightRequest="{Binding PictureHeightWidth}"
                            HorizontalOptions="Center"
                            Source="{Binding CurrentUser.ImageProfile}"
                            VerticalOptions="Center"
                            WidthRequest="{Binding PictureHeightWidth}" />
                        <Image
                            HeightRequest="{Binding SeparatorHeight}"
                            HorizontalOptions="Center"
                            Source="{extension:ImageSource LogoPROJECT.png}" />
                        <AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
                            <control:CustomEntry
                                AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                                AbsoluteLayout.LayoutFlags="All"
                                BackgroundColor="Transparent"
                                FontFamily="{extension:FontFamily Roboto_Light}"
                                FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
                                HasBorder="false"
                                Placeholder="pseudo"
                                PlaceholderColor="Gray"
                                Text="{Binding CurrentUser.Pseudo}"
                                TextColor="White"
                                XAlign="Center" />
                            <!--<BoxView
                                AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
                                AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
                                BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
                        </AbsoluteLayout>
                        <AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
                            <control:CustomEntry
                                AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                                AbsoluteLayout.LayoutFlags="All"
                                BackgroundColor="Transparent"
                                FontFamily="{extension:FontFamily Roboto_Light}"
                                FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
                                HasBorder="false"
                                Placeholder="email"
                                PlaceholderColor="Gray"
                                Text="{Binding CurrentUser.Email}"
                                TextColor="White"
                                XAlign="Center" />
                            <!--<BoxView
                                AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
                                AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
                                BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
                        </AbsoluteLayout>
                        <AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
                            <control:CustomEntry
                                AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                                AbsoluteLayout.LayoutFlags="All"
                                BackgroundColor="Transparent"
                                FontFamily="{extension:FontFamily Roboto_Light}"
                                FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
                                HasBorder="false"
                                Placeholder="firstname"
                                PlaceholderColor="Gray"
                                Text="{Binding CurrentUser.Firstname}"
                                TextColor="White"
                                XAlign="Center" />
                            <!--<BoxView
                                AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
                                AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
                                BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
                        </AbsoluteLayout>
                        <AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
                            <control:CustomEntry
                                AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                                AbsoluteLayout.LayoutFlags="All"
                                BackgroundColor="Transparent"
                                FontFamily="{extension:FontFamily Roboto_Light}"
                                FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
                                HasBorder="false"
                                Placeholder="lastname"
                                PlaceholderColor="Gray"
                                Text="{Binding CurrentUser.Lastname}"
                                TextColor="White"
                                XAlign="Center" />
                            <!--<BoxView
                                AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
                                AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
                                BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
                        </AbsoluteLayout>
                        <AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
                            <control:CustomEntry
                                AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                                AbsoluteLayout.LayoutFlags="All"
                                BackgroundColor="Transparent"
                                FontFamily="{extension:FontFamily Roboto_Light}"
                                FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
                                HasBorder="false"
                                Keyboard="Telephone"
                                Placeholder="phone number"
                                PlaceholderColor="Gray"
                                Text="{Binding CurrentUser.Number}"
                                TextColor="White"
                                XAlign="Center" />
                            <!--<BoxView
                                AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
                                AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
                                BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
                        </AbsoluteLayout>
                        <AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
                            <control:CustomEntry
                                AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                                AbsoluteLayout.LayoutFlags="All"
                                BackgroundColor="Transparent"
                                FontFamily="{extension:FontFamily Roboto_Light}"
                                FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
                                HasBorder="false"
                                IsPassword="True"
                                Placeholder="password"
                                PlaceholderColor="Gray"
                                Text="{Binding PasswordOne}"
                                TextColor="White"
                                XAlign="Center" />
                            <!--<BoxView
                                AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
                                AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
                                BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
                        </AbsoluteLayout>
                        <AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
                            <control:CustomEntry
                                AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                                AbsoluteLayout.LayoutFlags="All"
                                BackgroundColor="Transparent"
                                FontFamily="{extension:FontFamily Roboto_Light}"
                                FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
                                HasBorder="false"
                                IsPassword="True"
                                Placeholder="password (retype)"
                                PlaceholderColor="Gray"
                                Text="{Binding PasswordTwo}"
                                TextColor="White"
                                XAlign="Center" />
                            <!--<BoxView
                                AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
                                AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
                                BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
                        </AbsoluteLayout>
                    </StackLayout>
                </ScrollView>
                <AbsoluteLayout
                    AbsoluteLayout.LayoutBounds="0.5,1,1,0.1"
                    AbsoluteLayout.LayoutFlags="All"
                    BackgroundColor="{StaticResource NL_OrangeBeer}">
                    <control:CustomLabel
                        AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                        AbsoluteLayout.LayoutFlags="All"
                        FontFamily="{extension:FontFamily Roboto_Light}"
                        FontSize="35"
                        HorizontalTextAlignment="Center"
                        Text="Save and Return"
                        TextColor="White"
                        VerticalTextAlignment="Center" />
                    <control:CustomButton
                        AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                        AbsoluteLayout.LayoutFlags="All"
                        BackgroundColor="Transparent"
                        BorderColor="Transparent"
                        Clicked="OnSaveClicked" />
                </AbsoluteLayout>
                <AbsoluteLayout
                    AbsoluteLayout.LayoutBounds="0, 0, 0.1, 0.1"
                    AbsoluteLayout.LayoutFlags="All"
                    BackgroundColor="Transparent"
                    IsVisible="{Binding IsReturnVisible}">
                    <control:CustomImage
                        AbsoluteLayout.LayoutBounds="0.5, 0.5, 0.8, 0.8"
                        AbsoluteLayout.LayoutFlags="All"
                        Aspect="AspectFit"
                        Source="{extension:ImageSource cross.png}" />
                    <control:CustomButton
                        AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                        AbsoluteLayout.LayoutFlags="All"
                        BackgroundColor="Transparent"
                        BorderColor="Transparent"
                        Clicked="OnReturnClicked" />
                </AbsoluteLayout>
            </AbsoluteLayout>
        </AbsoluteLayout>
    </ContentPage.Content>
</ContentPage>

Where extension:FontSize is coming from :

[ContentProperty("FontSize")]
public class FontSizeExtension : IMarkupExtension
{
    public double FontSize { get; set; }

    public object ProvideValue(IServiceProvider serviceProvider)
    {
        return Services.Sizing.FontSizeAdapter(FontSize);
    }
}

Sizing.cs

public class Sizing
{
    public static double FontSizeAdapter(double fontSize)
    {
        switch (Device.RuntimePlatform)
        {
            case "Android":
                return (fontSize / 2);
            case "iOS":
                return fontSize;
            case "Windows":
            case "WinPhone":
                return fontSize;
            default:
                return fontSize;
        }
    }
}

However, when I do FontSize="{extention:FontSize {x:StaticResource EntryFontSize}}" it throws an exception that says that the value cannot be null.. How can I use the both at the same time? I mean the x:StaticResource and the Extension

Thank !

Upvotes: 2

Views: 1178

Answers (1)

Sharada
Sharada

Reputation: 13601

Edit - 08/18

1. Ensure prefix is correctly defined and used

Make sure to check the namespace provided for prefix is correct for your markup extension, and that there is no spelling mistake while specifying the prefix. This should resolve the 'Value cannot be null' error.

2. Specify property name while using nested markup-extensions

The property-name of extension needs to be specified while using nested markup-extension. Otherwise, my tests show, it is treated as a string value and assigned to default content property. This should resolve the error 'Input string was not in a correct format'.


Solution-1: Specify property-name

<control:CustomEntry
       AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
       AbsoluteLayout.Flags="All"
   ...
       FontSize="{extension:FontSize FontSize={x:StaticResource EntryFontSize}}"
   .../>

Solution-2: You can simplify this further by adding a StaticResourceKey property in markup extension:

[ContentProperty("FontSize")]
public class FontSizeExtension : IMarkupExtension
{
    public double FontSize { get; set; }
    public string StaticResourceKey { get; set; }

    public object ProvideValue(IServiceProvider serviceProvider)
    {
        if (serviceProvider == null)
            throw new ArgumentNullException(nameof(serviceProvider));

        if (StaticResourceKey != null)
        {
            var staticResourceExtension = new StaticResourceExtension { Key = StaticResourceKey };
            FontSize = (double)staticResourceExtension.ProvideValue(serviceProvider);
        }

        return Services.Sizing.FontSizeAdapter(FontSize);
    }
}

and usage can be:

   ...
       FontSize="{extension:FontSize StaticResourceKey=EntryFontSize}}"
   ...

Upvotes: 3

Related Questions