XAML资源字典中的算术运算 我想做什么

XAML资源字典中的算术运算 我想做什么,xaml,xamarin.forms,resourcedictionary,ivalueconverter,Xaml,Xamarin.forms,Resourcedictionary,Ivalueconverter,我最近一直在探索XAML资源字典。它们非常强大,但为了减少(甚至进一步)为适应任何修改而需要进行的更改,我想使用一些基本的算术运算来更改条目的HeightRequest属性 我已经很好地利用了OnPlatform和OnIdiom来实现不同的功能,比如FontSize 对于iOS平台,我想对条目20+(FontSize)进行HeightRequest。已使用OnIdiom设置了FontSize(平板电脑略微增加) 在一个完美的世界里,我试图做的核心事情可能看起来像 什么“有效” 如果我结合使用O

我最近一直在探索XAML资源字典。它们非常强大,但为了减少(甚至进一步)为适应任何修改而需要进行的更改,我想使用一些基本的算术运算来更改
条目的
HeightRequest
属性

我已经很好地利用了
OnPlatform
OnIdiom
来实现不同的功能,比如
FontSize

对于iOS平台,我想对条目
20+(FontSize)
进行
HeightRequest
。已使用
OnIdiom
设置了
FontSize
(平板电脑略微增加)

在一个完美的世界里,我试图做的核心事情可能看起来像

什么“有效” 如果我结合使用
OnIdiom
OnPlatform
,我就有了一个有效的解决方案

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamarinDesigner.App"
             xmlns:local="clr-namespace:XamarinDesigner"
             >
    <Application.Resources>
        <ResourceDictionary>
            <OnIdiom x:Key="StandardFontSize" x:TypeArguments="x:Double"  Tablet="22" Phone="18"/>
            <Style x:Key="MyEntry" TargetType="Entry">
                <Setter Property="FontSize" Value="{DynamicResource StandardFontSize}"/>
                <Setter Property="HeightRequest">
                    <Setter.Value>
                        <OnIdiom x:TypeArguments="x:Double">
                            <OnIdiom.Phone>
                                <OnPlatform x:TypeArguments="x:Double" iOS="30"/>
                            </OnIdiom.Phone>
                            <OnIdiom.Tablet>
                                <OnPlatform x:TypeArguments="x:Double" iOS="40"/>
                            </OnIdiom.Tablet>
                        </OnIdiom>
                    </Setter.Value>
                </Setter>
                <Setter Property="VerticalOptions" Value="Center"/>
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>
我不完全理解转换器的使用,App.xaml中的值内部的
{Binding}
对我来说也是新的东西。看看随转换器提供的示例,我认为我接近正确,可能只需要朝正确的方向推动一下


是否可以在
App.xaml
中单独(或使用转换器)执行这种基本的算术功能?我希望能在这个文件中包含尽可能多的内容

我在搜索中发现的其他解决方案提到了viewmodel的使用,但这是一个“全局”更改,我希望应用于每个平台/习惯用法的每个条目,因此我看不出这种调整是如何工作的


谢谢你的时间

应用程序崩溃的原因之一是转换器在ResourceDictionary之外

解决方案1

仅当分配了BindingContext时才应使用绑定,因此您需要在cs文件中分配它

App.cs:

public App()
{
    InitializeComponent();
    BindingContext = new { EntryHeightRequest = 10 };
    MainPage = ...
}
App.xaml:

<ResourceDictionary>
    <local:ArithmeticConverter x:Key="AScript"/>
    <OnIdiom x:Key="StandardFontSize" x:TypeArguments="x:Double"  Tablet="22" Phone="18"/>
    <Style x:Key="MyEntry" TargetType="Entry">
        <Setter Property="FontSize" Value="{DynamicResource StandardFontSize}" /> 
        <Setter Property="HeightRequest" Value="{Binding EntryHeightRequest, Converter={StaticResource AScript},ConverterParameter="{StaticResource StandardFontSize}"/>
        <Setter Property="VerticalOptions" Value="Center"/>
    </Style>
</ResourceDictionary>


如果你在你的转换器里放置一个断点,你就会明白为什么它会崩溃。。。首先,与链接的示例相反,您没有绑定到任何东西,因此转换器中的
值将为null。此外,示例中使用的正则表达式很可能不适合您的需要。是的,你可以毫无问题地拥有App.xaml中的所有内容。这里有一个更简洁的解决方案:直接绑定到你的
StandardFontSize
,然后在转换器内部进行你需要的任何运算。这样你就不需要,
ConverterParameter
和正则表达式了。嗯,这是我可以做到这一点的一种方法,但我想这会让我的用例/意图变得有点棘手。我正在有效地尝试设置CSS的等价物,并尝试在可能的情况下避免绑定,因为我正在检查更新样式的现有应用程序(目前没有使用资源字典)。许多页面已经有相当复杂的绑定设置,可以绑定到其他类和模型。不管怎样,我会玩这个概念,看看我能想出什么!谢谢你的回复。我非常期待看到你会想出什么。一旦有了解决方案,请发布它。即使转换器放在资源字典中,它仍然会崩溃,因为还有其他更“严重”的问题,就像我在评论中提到的那样。
<ResourceDictionary>
    <local:ArithmeticConverter x:Key="AScript"/>
    <OnIdiom x:Key="StandardFontSize" x:TypeArguments="x:Double"  Tablet="22" Phone="18"/>
    <Style x:Key="MyEntry" TargetType="Entry">
        <Setter Property="FontSize" Value="{DynamicResource StandardFontSize}" /> 
        <Setter Property="HeightRequest" Value="{Binding EntryHeightRequest, Converter={StaticResource AScript},ConverterParameter="{StaticResource StandardFontSize}"/>
        <Setter Property="VerticalOptions" Value="Center"/>
    </Style>
</ResourceDictionary>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if(value is int constant && parameter is OnIdiom<double> dynamicSize)
        return constant + dynamicSize.GetValue();
    return -1;
}
    public static T GetValue<T>(this OnIdiom<T> idiom)
    {
        switch(Device.Idiom)
        {
            case TargetIdiom.Phone:
                return idiom.Phone;

            case TargetIdiom.Desktop:
                return idiom.Desktop;

            case TargetIdiom.Tablet:
                return idiom.Tablet;

            case TargetIdiom.TV:
                return idiom.TV;

            case TargetIdiom.Watch:
                return idiom.Watch;

            default:
                throw new NotSupportedException();
        }
    }
<Setter Property="HeightRequest" Value="{OnIdiom Default=10, Converter={StaticResource AScript}, ConverterParameter={StaticResource StandardFontSize}}" />