是否可以在 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() 在代码隐藏文件中不可用。

OnIdiomOnPlatform 可以一起使用吗?

【问题讨论】:

【参考方案1】:

在代码中有效的一个选项是使用

if(Device.OS == TargetPlatform.Windows && Device.Idiom == TargetIdiom.Phone)
    this.innerGrid.ColumnDefinitions.First().Width = new GridLength(100);

覆盖现有的 Xaml 定义。 innerGrid 是 Xaml 中使用的 Grid 的名称。

【讨论】:

【参考方案2】:

Xamarin.FormsXaml 示例:

<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.OSWindowsDevice.IdiomDesktop。 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.Forms Previewer

Xamarin XAML语言教程Xamarin.Forms中改变活动指示器颜色

在 Xamarin.Forms 上的 XAML 中将 BindingContext 设置为 ViewModel

如何用xamarin.forms xaml