How to set Platform Specfic Values for Grid.Row and Grid.Column in XAML

VenkataSivaprasadReddyPulagamVenkataSivaprasadReddyPulagam USMember ✭✭✭
edited September 2017 in Xamarin.Forms

Hi friends,

how to set different values like <Label Grid.Row="0" Grid.RowSpan="2"> for ios and <Label Grid.Row="0" Grid.RowSpan="3"> for android in xaml

it is possible in C#, and how to manage this scenario in XAML
for different platforms.

Best Answer

  • ClintStLaurentClintStLaurent US ✭✭✭✭✭
    Accepted Answer

    Some OnPlatform examples in XAML

                <OnPlatform x:Key="LargeFontSize"
                            x:TypeArguments="x:Double"
                            Android="30.0"
                            WinPhone="30.0"
                            iOS="30.0" />
    
    
                <OnPlatform x:Key="LocalStoragePath"
                            x:TypeArguments="x:String"
                            Android="/sdcard"
                            WinPhone="D:\"
                            iOS="" />
    
                <OnPlatform x:Key="FontMonospace"
                            x:TypeArguments="x:String">
                    <OnPlatform.Android>monospace</OnPlatform.Android>
                    <OnPlatform.iOS>Courier New</OnPlatform.iOS>
                </OnPlatform>
    
    
                <OnPlatform x:TypeArguments="View">
                    <OnPlatform.iOS>
                        <Entry x:Name="EntPasswordIos"
                               HorizontalOptions="FillAndExpand"
                               Text="{Binding AppVM.EnteredPassword}"
                               VerticalOptions="FillAndExpand"
                               Style="{StaticResource EntryStyleLrg}"
                               IsPassword="True"/>
                    </OnPlatform.iOS>
                    <OnPlatform.Android>
                        <Entry x:Name="EntPasswordDroid"
                               HorizontalOptions="FillAndExpand"
                               Placeholder="{Binding AppVM.EnteredPassword}"
                               PlaceholderColor="Black"
                               VerticalOptions="Start"
                               Style="{StaticResource EntryStyleLrg}" 
                               IsPassword="True"/>
                    </OnPlatform.Android>
                    <OnPlatform.WinPhone>
                        <Entry x:Name="EntPasswordWin"
                               HorizontalOptions="FillAndExpand"
                               Text="{Binding AppVM.EnteredPassword}"
                               VerticalOptions="FillAndExpand"
                               Style="{StaticResource EntryStyleLrg}" 
                               IsPassword="True"/>
                    </OnPlatform.WinPhone>
                </OnPlatform>
    
    
    

Answers

  • N_BauaN_Baua INMember ✭✭✭✭✭

    Hi @VenkataSivaprasadReddyPulagam ,

    I would rather suggest use layouts based on the device OS and render the values/controls accordingly.

    Hope it helps.
    -- N Baua

  • Hi N_Baua,

    Thank You for the reply.

    But i want this scenario in xaml
    <Label Grid.Row="0" Grid.RowSpan="2"> for ios
    and
    <Label Grid.Row="0" Grid.RowSpan="3"> for android

  • N_BauaN_Baua INMember ✭✭✭✭✭

    @VenkataSivaprasadReddyPulagam said:
    Hi N_Baua,

    Thank You for the reply.

    But i want this scenario in xaml
    <Label Grid.Row="0" Grid.RowSpan="2"> for ios
    and
    <Label Grid.Row="0" Grid.RowSpan="3"> for android

    Not an easy way that I am aware of to do likewise.

    Okey, may be what you can do is use the Binding as with MVVM

    <Label Grid.Row="0" Grid.RowSpan="{Binding ColSpanRowCount}">
    where ColSpanRowCount is a property which you can easily populate from your ViewModel based on your OS.

    Hope it helps.
    N Baua

  • Hi @N_Baua,
    Thank you, the above solution really helped, But unfortunately i am not using MVVM.

    I made this but the below code gives an error
    do you have any idea about it

    Value was an invalid value for RowSpan Parameter name: value

    <Grid x:Name="gridAlertTextHolder" RowSpacing="0" Grid.Column="0" Grid.Row="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"> 
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="1*"/>
                            </Grid.ColumnDefinitions>
                            <Grid.Resources>
                                <ResourceDictionary>
                                    <x:Int32 x:Key="PlatformColumn">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="0" />
                                            <On Platform="Android, WinPhone, Windows" Value="3" />
                                        </OnPlatform>
                                    </x:Int32>
                                    <x:Int32 x:Key="PlatformColumnSpan">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="4" />
                                            <On Platform="Android, WinPhone, Windows" Value="1" />
                                        </OnPlatform>
                                    </x:Int32>
                                    <x:Int32 x:Key="PlatformRow">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="2" />
                                            <On Platform="Android, WinPhone, Windows" Value="2" />
                                        </OnPlatform>
                                    </x:Int32>
                                    <x:Int32 x:Key="PlatformRowSpan">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="1" />
                                            <On Platform="Android, WinPhone, Windows" Value="1" />
                                        </OnPlatform>
                                    </x:Int32>
                                </ResourceDictionary>
                            </Grid.Resources>
                            <Label x:Name="lblAlertHeading" Text="Alert" FontSize="Medium" FontAttributes="Bold" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="0" Grid.RowSpan="1">
                            </Label>
                            <Label x:Name="lblAlertMessage" Text="" FontSize="Medium" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="1">
                            </Label>
                            <Button x:Name="btnAlert" Text="OK" Grid.Column="{StaticResource PlatformColumn}" Grid.Row="{StaticResource PlatformRow}" Grid.RowSpan="{StaticResource PlatformRowSpan}" Grid.ColumnSpan="{StaticResource PlatformColumnSpan}">
                            </Button>
                        </Grid>
    
  • Hi @ClintStLaurent ,

    Thank You for the reply.

    I need to implement in XAML
    i want to set Grid.ColumnSpan in XAML based on platform.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭
    Accepted Answer

    Some OnPlatform examples in XAML

                <OnPlatform x:Key="LargeFontSize"
                            x:TypeArguments="x:Double"
                            Android="30.0"
                            WinPhone="30.0"
                            iOS="30.0" />
    
    
                <OnPlatform x:Key="LocalStoragePath"
                            x:TypeArguments="x:String"
                            Android="/sdcard"
                            WinPhone="D:\"
                            iOS="" />
    
                <OnPlatform x:Key="FontMonospace"
                            x:TypeArguments="x:String">
                    <OnPlatform.Android>monospace</OnPlatform.Android>
                    <OnPlatform.iOS>Courier New</OnPlatform.iOS>
                </OnPlatform>
    
    
                <OnPlatform x:TypeArguments="View">
                    <OnPlatform.iOS>
                        <Entry x:Name="EntPasswordIos"
                               HorizontalOptions="FillAndExpand"
                               Text="{Binding AppVM.EnteredPassword}"
                               VerticalOptions="FillAndExpand"
                               Style="{StaticResource EntryStyleLrg}"
                               IsPassword="True"/>
                    </OnPlatform.iOS>
                    <OnPlatform.Android>
                        <Entry x:Name="EntPasswordDroid"
                               HorizontalOptions="FillAndExpand"
                               Placeholder="{Binding AppVM.EnteredPassword}"
                               PlaceholderColor="Black"
                               VerticalOptions="Start"
                               Style="{StaticResource EntryStyleLrg}" 
                               IsPassword="True"/>
                    </OnPlatform.Android>
                    <OnPlatform.WinPhone>
                        <Entry x:Name="EntPasswordWin"
                               HorizontalOptions="FillAndExpand"
                               Text="{Binding AppVM.EnteredPassword}"
                               VerticalOptions="FillAndExpand"
                               Style="{StaticResource EntryStyleLrg}" 
                               IsPassword="True"/>
                    </OnPlatform.WinPhone>
                </OnPlatform>
    
    
    
  • Hi @ClintStLaurent ,

    Thank you for the reply
    This Solution also meets my current requirement.

    I made this but the below code gives an error

    Value was an invalid value for RowSpan Parameter name: value

    <Grid x:Name="gridAlertTextHolder" RowSpacing="0" Grid.Column="0" Grid.Row="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"> 
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="1*"/>
                            </Grid.ColumnDefinitions>
                            <Grid.Resources>
                                <ResourceDictionary>
                                    <x:Int32 x:Key="PlatformColumn">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="0" />
                                            <On Platform="Android, WinPhone, Windows" Value="3" />
                                        </OnPlatform>
                                    </x:Int32>
                                    <x:Int32 x:Key="PlatformColumnSpan">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="4" />
                                            <On Platform="Android, WinPhone, Windows" Value="1" />
                                        </OnPlatform>
                                    </x:Int32>
                                    <x:Int32 x:Key="PlatformRow">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="2" />
                                            <On Platform="Android, WinPhone, Windows" Value="2" />
                                        </OnPlatform>
                                    </x:Int32>
                                    <x:Int32 x:Key="PlatformRowSpan">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="1" />
                                            <On Platform="Android, WinPhone, Windows" Value="1" />
                                        </OnPlatform>
                                    </x:Int32>
                                </ResourceDictionary>
                            </Grid.Resources>
                            <Label x:Name="lblAlertHeading" Text="Alert" FontSize="Medium" FontAttributes="Bold" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="0" Grid.RowSpan="1">
                            </Label>
                            <Label x:Name="lblAlertMessage" Text="" FontSize="Medium" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="1">
                            </Label>
                            <Button x:Name="btnAlert" Text="OK" Grid.Column="{StaticResource PlatformColumn}" Grid.Row="{StaticResource PlatformRow}" Grid.RowSpan="{StaticResource PlatformRowSpan}" Grid.ColumnSpan="{StaticResource PlatformColumnSpan}">
                            </Button>
                        </Grid>
    

    But i hope with your code instead of setting grid.columnspan property i will replace the entire view based on platform.
    This also meets my requirement thank you
    If you have any idea about the code and error that i provided above please let me know.

    Thank you.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    do you have any idea about it
    Value was an invalid value for RowSpan Parameter name: value

    Grid.RowSpan="{StaticResource PlatformRowSpan}"

    No way of knowing since that resource doesn't appear in of the code you've shared

  • Hi @ClintStLaurent ,

    this resource is defined in the grid itself in the above code

        <Grid.Resources>
        <ResourceDictionary>
                                        <x:Int32 x:Key="PlatformColumn">
                                            <OnPlatform x:TypeArguments="x:Int32">
                                                <On Platform="iOS" Value="0" />
                                                <On Platform="Android, WinPhone, Windows" Value="3" />
                                            </OnPlatform>
                                        </x:Int32>
                                        <x:Int32 x:Key="PlatformColumnSpan">
                                            <OnPlatform x:TypeArguments="x:Int32">
                                                <On Platform="iOS" Value="4" />
                                                <On Platform="Android, WinPhone, Windows" Value="1" />
                                            </OnPlatform>
                                        </x:Int32>
                                        <x:Int32 x:Key="PlatformRow">
                                            <OnPlatform x:TypeArguments="x:Int32">
                                                <On Platform="iOS" Value="2" />
                                                <On Platform="Android, WinPhone, Windows" Value="2" />
                                            </OnPlatform>
                                        </x:Int32>
                                        <x:Int32 x:Key="PlatformRowSpan">
                                            <OnPlatform x:TypeArguments="x:Int32">
                                                <On Platform="iOS" Value="1" />
                                                <On Platform="Android, WinPhone, Windows" Value="1" />
                                            </OnPlatform>
                                        </x:Int32>
                                    </ResourceDictionary>
        </GridResources>
    

    but still it give the error for rowspan and columnspan but not getting any error for column number and row number.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭
    edited September 2017

    My first thought is that if the column numbers work, but the spans don't, then the span must not be of the right type.
    I made up a dummy project to test and pasted in your definition. I get the same error:
    09-27 07:55:24.391 I/MonoDroid( 5203): System.ArgumentException: Value was an invalid value for ColumnSpan

    Replaced Int32 with Double - Fail
    Upon closer examination the XAML intellisense hint tells you that it expected an int
    Hmmm... Pondering...
    Replaced Int32 with Int16 - no complaint at design time. But differerent error at runtime
    09-27 08:06:08.931 I/MonoDroid( 7095): Xamarin.Forms.Xaml.XamlParseException: Position 43:17. Cannot assign property "ColumnSpan": Property does not exists, or is not assignable, or mismatching type between value and property
    So it really didn't like the Int16
    Int64? Nope, intellisense shows it doesn't like that.

    I think you found a genuine bug worth reporting on Bugzilla.

  • NMackayNMackay GBInsider, University mod
    edited September 2017

    I can't see how you can set it either using OnPlatform, there's only a get & set which expects or return int.

  • Hi @NMackay ,
    you are using Grid.ColumnSpan inside the grid itself it is a property only able to set for childs of grid
    you are doing in a wrong procedure.

        <Grid>
        .....definitions...
        <label Grid.ColumnSpan="1" Grid.RowSpan="1"/>
        </Grid>
    

    I am now trying to make the page entirely on to XAML alone except event handlers as that is not possible in XAML
    so I defined resources for grid and i am using them in code as below instead of integers(1 in the above code)

    <Grid x:Name="gridAlertTextHolder" RowSpacing="0" Grid.Column="0" Grid.Row="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"> 
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="1*"/>
                            </Grid.ColumnDefinitions>
                            <Grid.Resources>
                                <ResourceDictionary>
                                    <x:Int32 x:Key="PlatformColumn">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="0" />
                                            <On Platform="Android, WinPhone, Windows" Value="3" />
                                        </OnPlatform>
                                    </x:Int32>
                                    <x:Int32 x:Key="PlatformColumnSpan">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="4" />
                                            <On Platform="Android, WinPhone, Windows" Value="1" />
                                        </OnPlatform>
                                    </x:Int32>
                                    <x:Int32 x:Key="PlatformRow">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="2" />
                                            <On Platform="Android, WinPhone, Windows" Value="2" />
                                        </OnPlatform>
                                    </x:Int32>
                                    <x:Int32 x:Key="PlatformRowSpan">
                                        <OnPlatform x:TypeArguments="x:Int32">
                                            <On Platform="iOS" Value="1" />
                                            <On Platform="Android, WinPhone, Windows" Value="1" />
                                        </OnPlatform>
                                    </x:Int32>
                                </ResourceDictionary>
                            </Grid.Resources>
                            <Label x:Name="lblAlertHeading" Text="Alert" FontSize="Medium" FontAttributes="Bold" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="0" Grid.RowSpan="1">
                            </Label>
                        </Grid>
    

    like above

  • NMackayNMackay GBInsider, University mod

    @VenkataSivaprasadReddyPulagam

    I disagree, you should be able to set the column span using OnPlatform

Sign In or Register to comment.