19

For UWP I need a different size for the width of a column in a Grid. Additionally, the value should be different on tablet and on smartphone.

The following code crashes the app

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

with

Type OnIdiom.Phone not found in xmlns http://xamarin.com/schemas/2014/forms

The code is in a ViewCell. So I can't use an additional ResourceDictionary and also OnSizeAllocated() is not available in the code behind file.

Is it possible to use OnIdiom and OnPlatform together?

testing
  • 19,681
  • 50
  • 236
  • 417

5 Answers5

30

OnIdiom, just like OnPlatform is an object you have to declare. In your case, you're setting OnIdiom.Phone property to an object that doesn't have those.

Your Xaml should look more like:

<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>
Stephane Delcroix
  • 16,134
  • 5
  • 57
  • 85
  • I tried to run the app on the local machine. Here the 200 width is not respected. Shouldn't it fall into the `Tablet` category? – testing Oct 19 '16 at 11:11
  • `Device.OS` is `Windows` and `Device.Idiom` is `Desktop`. Are there any definitions for that in the XAML available? `WinPhone` worked fine before. – testing Oct 19 '16 at 11:20
  • 1
    support for `Desktop` in OnIdiom landed a few days ago https://github.com/xamarin/Xamarin.Forms/pull/420. The fix will be present in the upcoming 2.3.4-pre1 – Stephane Delcroix Oct 19 '16 at 13:22
18

Much nicer syntax as of Xamarin.Forms v3.2 (via new built-in XAML extensions):

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="{OnIdiom 
        Phone= {OnPlatform iOS=*, Android=*, UWP=100 },
        Tablet= {OnPlatform iOS=*, Android=*, UWP=200 }}">
    </ColumnDefinition>
</Grid.ColumnDefinitions>
Mark Z.
  • 2,127
  • 16
  • 33
4

Xamarin.Forms Xaml Example:

<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>
SushiHangover
  • 73,120
  • 10
  • 106
  • 165
  • OK, I multiply the complete `Grid` definition. But I have a few named `Label` in it and one can't have multiple labels with the same name. Any solution for this? – testing Oct 19 '16 at 11:05
3

Here is the solution to mix OnIdiom and OnPlatform in xaml. For Example, there are variations in stack layout padding then we can do this as follows -

   <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>
Waaheeda
  • 394
  • 3
  • 14
0

One option which works in code is to use

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

to overwrite the existing Xaml definition. innerGrid is the name of the Grid used in the Xaml.

testing
  • 19,681
  • 50
  • 236
  • 417