testing
testing

Reputation: 20289

Is it possible to mix OnIdiom and OnPlatform in XAML (Xamarin.Forms)?

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?

Upvotes: 20

Views: 12268

Answers (5)

Vahida Havaldar
Vahida Havaldar

Reputation: 524

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>

Upvotes: 3

Mark Z.
Mark Z.

Reputation: 2447

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>

Upvotes: 19

Stephane Delcroix
Stephane Delcroix

Reputation: 16232

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>

Upvotes: 30

SushiHangover
SushiHangover

Reputation: 74184

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>

Upvotes: 4

testing
testing

Reputation: 20289

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.

Upvotes: 0

Related Questions