我做了一些研究,但找不到针对自己问题的答案。我有一个XF应用,并使用以下代码设置Label
的样式:
<Style x:Key="Heading2Text" TargetType="Label">
<Setter Property="FontSize">
<Setter.Value>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS" Value="{DynamicResource Heading2TextFontSizeiOS}"/>
<On Platform="Android" Value="{DynamicResource Heading2TextFontSizeAndroid}"/>
</OnPlatform>
</Setter.Value>
</Setter>
</Style>
在我的资源中:
Current.Resources["Heading2TextFontSizeiOS"] = 10.75 * vScale;
Current.Resources["Heading2TextFontSizeAndroid"] = 20.5 * vScale;
这给我一个错误:Specified cast is not valid
但是,如果我像下面的代码那样指定值,那么它将起作用。
<Style x:Key="Heading2Text" TargetType="Label">
<Setter Property="FontSize">
<Setter.Value>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS" Value="14"/>
<On Platform="Android" Value="20"/>
</OnPlatform>
</Setter.Value>
</Setter>
</Style>
有人知道我在做什么错吗?
编辑:
我意识到了问题所在。 Current.Resources["Heading2TextFontSizeiOS"]
是一个对象,因此是错误。有人对如何解决这个问题有什么建议吗?
vScale
在App.xaml.cs
中这样声明:
public static double vScale;
在资源类中:
vScale = height > 700 ? 1.4 : height / 568;
这是我得到的例外:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidCastException: Specified cast is not valid.
at Xamarin.Forms.OnPlatform`1[T].op_Implicit (Xamarin.Forms.OnPlatform`1[T] onPlatform) [0x00036] in D:\a\1\s\Xamarin.Forms.Core\OnPlatform.cs:75
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0003b] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
--- End of inner exception stack trace ---
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00054] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at Xamarin.Forms.BindableProperty.TryConvert (System.Object& value) [0x000cf] in D:\a\1\s\Xamarin.Forms.Core\BindableProperty.cs:341
at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes) [0x00041] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:386
at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value, System.Boolean fromStyle, System.Boolean checkAccess) [0x0003d] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:572
at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value, System.Boolean fromStyle) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:356
at Xamarin.Forms.Setter.Apply (Xamarin.Forms.BindableObject target, System.Boolean fromStyle) [0x000ba] in D:\a\1\s\Xamarin.Forms.Core\Setter.cs:75
at Xamarin.Forms.Style.ApplyCore (Xamarin.Forms.BindableObject bindable, Xamarin.Forms.Style basedOn) [0x0001e] in D:\a\1\s\Xamarin.Forms.Core\Style.cs:132
at Xamarin.Forms.Style.Xamarin.Forms.IStyle.Apply (Xamarin.Forms.BindableObject bindable) [0x0002b] in D:\a\1\s\Xamarin.Forms.Core\Style.cs:95
at Xamarin.Forms.MergedStyle.SetStyle (Xamarin.Forms.IStyle implicitStyle, System.Collections.Generic.IList`1[T] classStyles, Xamarin.Forms.IStyle style) [0x00156] in D:\a\1\s\Xamarin.Forms.Core\MergedStyle.cs:180
at Xamarin.Forms.MergedStyle.set_Style (Xamarin.Forms.IStyle value) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\MergedStyle.cs:37
at Xamarin.Forms.NavigableElement+<>c.<.cctor>b__20_0 (Xamarin.Forms.BindableObject bindable, System.Object oldvalue, System.Object newvalue) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Shell\NavigableElement.cs:16
at Xamarin.Forms.BindableObject.SetValueActual (Xamarin.Forms.BindableProperty property, Xamarin.Forms.BindableObject+BindablePropertyContext context, System.Object value, System.Boolean currentlyApplying, Xamarin.Forms.Internals.SetValueFlags attributes, System.Boolean silent) [0x00120] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:624
at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes) [0x0015b] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:422
at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value, System.Boolean fromStyle, System.Boolean checkAccess) [0x0003d] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:572
at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:122
at Xamarin.Forms.VisualElement.set_Style (Xamarin.Forms.Style value) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\VisualElement.cs:394
答案 0 :(得分:0)
有两件事要看。
这是将基于XAML的DynamicResource
与OnPlatform
结合使用的当前限制。
这应该可以,但不能:
<Style x:Key="Heading2Text" TargetType="Button">
<Style.Setters>
<Setter Property="FontSize">
<OnPlatform x:TypeArguments="x:Double">
<On Platform="Android">
<DynamicResource Key="Heading2TextFontSizeAndroid" />
</On>
</OnPlatform>
</Setter>
</Style.Setters>
</Style>
您可以通过代码进行操作:
someLabelInstance.SetDynamicResource(Label.FontSizeProperty, "Heading2TextFontSizeAndroid");
Resources["Heading2TextFontSizeAndroid"] = 10 * 4.0;
注意:我已经看到这个问题飘浮了很多年,因此,如果有一种方法可以直接在XAML中使用带有OnPlatform的DynamicResource,而不是将其转换为StaticResource的方法,那么我很乐意看到>
如果将其转换为使用StaticResource,它将起作用,但是,如果您确实需要以动态方式更改这些属性,那当然是不可能的。
您是否真的需要将其作为动态绑定的属性?
似乎这可能是您正在执行的设备特定计算,因此只能执行一次。另外,静态资源更快,占用的内存更少,因为所有动态资源基本上都是绑定的属性。
如果可以在实例化ContentPage之前计算vScale = height > 700 ? 1.4 : height / 568;
,并且在该页面实例的生存期内不进行更改,则可以使用StaticResource
并首先更新其值。
<sys:Double x:Key="Heading2TextFontSizeAndroid">20</sys:Double>
<Style x:Key="Heading2Text" TargetType="Button">
<Style.Setters>
<Setter Property="FontSize">
<OnPlatform x:TypeArguments="x:Double">
<On Platform="Android">
<StaticResource Key="Heading2TextFontSizeAndroid" />
</On>
</OnPlatform>
</Setter>
</Style.Setters>
</Style>
// Before you instance the page that `Heading2TextFontSizeAndroid` will be use in
vScale = height > 700 ? 1.4 : height / 568;
Resources["Heading2TextFontSizeAndroid"] = vScale;
// Now you can instance the page and `vScale` is applied
var page = new SomeContentPage();