将 StaticResource 转化为 MarkupExtension

StaticResource into MarkupExtension

我目前正在尝试使用静态资源和我的条目 FontSize 属性 的扩展名。我有这段代码:

<?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>

extension:FontSize 的来源:

[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;
        }
    }
}

但是,当我执行 FontSize="{extention:FontSize {x:StaticResource EntryFontSize}}" 时,它抛出一个异常,指出该值不能为空。我如何同时使用两者?我的意思是 x:StaticResourceExtension

谢谢!

编辑 - 08/18

1.确保正确定义和使用前缀

确保检查为前缀提供的名称空间对于您的标记扩展是否正确,并且在指定前缀时没有拼写错误。这应该可以解决 'Value cannot be null' 错误。

2。使用嵌套标记扩展时指定 属性 名称

使用嵌套标记扩展时需要指定扩展名属性。否则,我的测试显示,它被视为字符串值并分配给默认内容 属性。这应该可以解决错误 'Input string was not in a correct format'.


解决方案-1:指定属性-name

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

Solution-2:您可以通过在标记扩展中添加 StaticResourceKey 属性 来进一步简化此问题:

[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);
    }
}

用法可以是:

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