在XAML(Xamarin.Forms)中,是否可以混合使用OnIdiom和OnPlatform?

19
对于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>

带有

在xmlns http://xamarin.com/schemas/2014/forms中找不到Type OnIdiom.Phone。

该代码位于ViewCell中。因此,我无法使用额外的ResourceDictionary,并且OnSizeAllocated()在代码后台文件中也不可用。

是否可能同时使用OnIdiomOnPlatform

5个回答

30

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宽度。难道它不应该属于“平板电脑”类别吗? - testing
Device.OSWindows,而 Device.IdiomDesktop。在 XAML 中是否有相应的定义?之前使用 WinPhone 没有问题。 - testing
1
OnIdiom对Desktop的支持已于几天前在https://github.com/xamarin/Xamarin.Forms/pull/420中实现。该修复程序将出现在即将发布的2.3.4-pre1版本中。 - Stephane Delcroix

18

自 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>

2
如果我想添加像iOS= 10,5,10,5,Android="15,10,15,10"这样需要逗号的值,该如何添加填充(padding)? - Ali123
3
只需使用单引号,例如 iOS='10,25'。 - Mark Z.

4

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”的元素,而且不能有多个同名标签。有什么解决办法吗? - testing

3

以下是在XAML中混合使用OnIdiom和OnPlatform的解决方案。例如,如果我们需要在StackLayout中设置不同的填充,则可以按照以下方式进行操作 -

   <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>

0

在编程中可行的一个选项是使用

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接