如何在Xamarin单平台Style中使用DynamicResource且无需后台代码
根因说明
你遇到的崩溃本质是两个问题叠加导致的:
- 仅配置单平台分支的
OnPlatform会为其他平台返回null,而Padding是值类型的Thickness,无法接收null值触发崩溃 DynamicResource是延迟解析的标记扩展对象,不是实际的Thickness值,OnPlatform无法直接将该标记扩展透传给属性,导致类型不匹配抛出异常。而StaticResource是XAML加载阶段就直接解析为实际值,所以可以正常运行。
可行实现方案(无后台代码)
方案1:补全OnPlatform默认分支(兼容性最好)
给OnPlatform增加Default分支兜底非目标平台的取值,避免空值,写法如下:
<Style TargetType="ContentPage" ApplyToDerivedTypes="True"> <Setter Property="BackgroundColor" Value="{DynamicResource PageBackgroundColor}"/> <Setter Property="Padding"> <Setter.Value> <OnPlatform x:TypeArguments="Thickness"> <On Platform="Android" Value="{DynamicResource ContentPagePadding}"/> <!-- 所有非Android平台统一使用该默认值,无需逐个声明平台 --> <On Platform="Default" Value="0"/> </OnPlatform> </Setter.Value> </Setter> </Style>
方案2:平台专属Setter(写法更简洁)
如果你的Xamarin.Forms版本在4.5以上,可以直接在Setter上指定生效平台,不需要嵌套OnPlatform:
<Style TargetType="ContentPage" ApplyToDerivedTypes="True"> <Setter Property="BackgroundColor" Value="{DynamicResource PageBackgroundColor}"/> <!-- 全局默认Padding,兜底非Android平台 --> <Setter Property="Padding" Value="0"/> <!-- 仅Android平台生效的Setter,会覆盖上面的默认值 --> <Setter Property="Padding" Value="{DynamicResource ContentPagePadding}" OnPlatform="Android"/> </Style>
方案3:资源层面区分平台(更易维护)
如果有多处用到这个平台专属的动态资源,可以直接在资源字典中定义平台差异化的资源,Style里直接引用即可:
<!-- App.xaml资源字典中定义 --> <Application.Resources> <OnPlatform x:Key="PlatformContentPagePadding" x:TypeArguments="Thickness"> <On Platform="Android" Value="{DynamicResource ContentPagePadding}"/> <On Platform="Default" Value="0"/> </OnPlatform> <!-- 你实际需要动态调整的Padding资源 --> <Thickness x:Key="ContentPagePadding">16,20,16,20</Thickness> </Application.Resources> <!-- Style中直接引用 --> <Style TargetType="ContentPage" ApplyToDerivedTypes="True"> <Setter Property="BackgroundColor" Value="{DynamicResource PageBackgroundColor}"/> <Setter Property="Padding" Value="{DynamicResource PlatformContentPagePadding}"/> </Style>
内容的提问来源于stack exchange,提问作者Dennis van Opstal
相关产品推荐
相关产品推荐

