是否可以在 XAML (Xamarin.Forms) 中混合 OnIdiom 和 OnPlatform?
Posted
技术标签:
【中文标题】是否可以在 XAML (Xamarin.Forms) 中混合 OnIdiom 和 OnPlatform?【英文标题】:Is it possible to mix OnIdiom and OnPlatform in XAML (Xamarin.Forms)? 【发布时间】:2017-02-27 21:43:13 【问题描述】:对于 UWP,我需要为 Grid
中的列的宽度设置不同的大小。此外,平板电脑和智能手机上的值应该不同。
以下代码使应用程序崩溃
<ColumnDefinition>
<ColumnDefinition.Width>
<OnIdiom.Phone>
<OnPlatform x:TypeArguments="GridLength" ios="*" android="*" WinPhone="100" />
</OnIdiom.Phone>
<OnIdiom.Tablet>
<OnPlatform x:TypeArguments="GridLength" iOS="*" Android="*" WinPhone="200" />
</OnIdiom.Tablet>
</ColumnDefinition.Width>
</ColumnDefinition>
与
类型 OnIdiom.Phone not found in xmlns http://xamarin.com/schemas/2014/forms
代码在ViewCell
中。所以我不能使用额外的ResourceDictionary
并且OnSizeAllocated()
在代码隐藏文件中不可用。
OnIdiom
和OnPlatform
可以一起使用吗?
【问题讨论】:
【参考方案1】:在代码中有效的一个选项是使用
if(Device.OS == TargetPlatform.Windows && Device.Idiom == TargetIdiom.Phone)
this.innerGrid.ColumnDefinitions.First().Width = new GridLength(100);
覆盖现有的 Xaml 定义。 innerGrid
是 Xaml 中使用的 Grid
的名称。
【讨论】:
【参考方案2】:Xamarin.Forms
Xaml 示例:
<OnPlatform x:TypeArguments="View">
<OnPlatform.Android>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition>
<ColumnDefinition.Width>
<OnIdiom x:TypeArguments="GridLength" Tablet="100" Phone="50" />
</ColumnDefinition.Width>
</ColumnDefinition>
<ColumnDefinition>
<ColumnDefinition.Width>
<OnIdiom x:TypeArguments="GridLength" Tablet="100" Phone="50" />
</ColumnDefinition.Width>
</ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
</OnPlatform.Android>
<OnPlatform.iOS>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition>
<ColumnDefinition.Width>
<OnIdiom x:TypeArguments="GridLength" Tablet="100" Phone="50" />
</ColumnDefinition.Width>
</ColumnDefinition>
<ColumnDefinition>
<ColumnDefinition.Width>
<OnIdiom x:TypeArguments="GridLength" Tablet="100" Phone="50" />
</ColumnDefinition.Width>
</ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
</OnPlatform.iOS>
</OnPlatform>
【讨论】:
好的,我将完整的Grid
定义相乘。但是我有几个名字叫Label
,一个不能有多个同名的标签。有什么解决办法吗?【参考方案3】:
OnIdiom
,就像OnPlatform
是一个你必须声明的对象。在您的情况下,您将 OnIdiom.Phone
属性设置为没有这些属性的对象。
您的 Xaml 应该看起来更像:
<ColumnDefinition>
<ColumnDefinition.Width>
<OnIdiom x:TypeArguments="GridLength">
<OnIdiom.Phone>
<OnPlatform x:TypeArguments="GridLength" iOS="*" Android="*" WinPhone="100" />
</OnIdiom.Phone>
<OnIdiom.Tablet>
<OnPlatform x:TypeArguments="GridLength" iOS="*" Android="*" WinPhone="200" />
</OnIdiom.Tablet>
</OnIdiom>
</ColumnDefinition.Width>
</ColumnDefinition>
【讨论】:
我尝试在本地机器上运行该应用程序。这里不考虑 200 宽度。它不应该属于Tablet
类别吗?
Device.OS
是 Windows
和 Device.Idiom
是 Desktop
。 XAML 中是否有任何定义? WinPhone
之前工作得很好。
对 OnIdiom 中的Desktop
的支持几天前在github.com/xamarin/Xamarin.Forms/pull/420 上登陆。该修复将出现在即将发布的 2.3.4-pre1【参考方案4】:
从 Xamarin.Forms v3.2 开始更好的语法(通过新的内置 XAML 扩展):
<Grid.ColumnDefinitions>
<ColumnDefinition Width="OnIdiom
Phone= OnPlatform iOS=*, Android=*, UWP=100 ,
Tablet= OnPlatform iOS=*, Android=*, UWP=200 ">
</ColumnDefinition>
</Grid.ColumnDefinitions>
【讨论】:
如果我想添加像 iOS= 10,5,10,5 , Android="15,10,15,10" 这样的填充怎么办。如何添加需要逗号之类的填充值? 只使用单引号,例如iOS='10,25'【参考方案5】:这是在 xaml 中混合 OnIdiom 和 OnPlatform 的解决方案。例如,堆栈布局填充有变化,那么我们可以这样做 -
<StackLayout.Padding>
<OnIdiom x:TypeArguments="Thickness">
<OnIdiom.Phone>
<OnPlatform x:TypeArguments="Thickness" iOS="0,40,0,0" Android="15,0" WinPhone="15,0" />
</OnIdiom.Phone>
<OnIdiom.Tablet>
<OnPlatform x:TypeArguments="Thickness" iOS="15,0" Android="15,0" WinPhone="15,0" />
</OnIdiom.Tablet>
</OnIdiom>
</StackLayout.Padding>
【讨论】:
以上是关于是否可以在 XAML (Xamarin.Forms) 中混合 OnIdiom 和 OnPlatform?的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Forms XAML的辅助功能Code Snippet
如何在 XAML [Xamarin.Forms] 中使用 String 以外的类型设置自定义属性值
Xamarin XAML语言教程Xamarin.Forms中改变活动指示器颜色