<?xml
version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="pav.LayoutsExample.MainPage">
<StackLayout>
<Label Text="First
name"/>
<Entry Placeholder="John" />
<Label Text="Last
name"/>
<Entry Placeholder="Doe"/>
<Label Text="Birthdate"/>
<DatePicker />
<Label Text="Phone
number"/>
<Entry Placeholder="519 979 1337" Keyboard="Numeric"/>
<Label Text="Email"/>
<Entry Placeholder="first.last@domain.com" Keyboard="Email"/>
</StackLayout>
</ContentPage>
now you can see that if the orientation is not specified then the default is vertical. with that said you can also see that the elements do not space themselves out nicely, it's hard to tell which label corresponds to which textbox. the Stacklayout container has a property called Spacing which defines a decimal number the specifies the amount of space between elements, it defaults to 6. What we are going to do is group all of the complementary labels with their textbox's inside their own stacklayouts and give those nested stacklaouts a spacing of 0, then increase the root stacklayouts spacing to 10.
<?xml
version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="pav.LayoutsExample.MainPage">
<ContentPage.Resources>
<Style TargetType="StackLayout">
<Setter Property="Spacing" Value="0"/>
</Style>
</ContentPage.Resources>
<StackLayout Spacing="10" Padding="5">
<StackLayout>
<Label Text="First
name" />
<Entry Placeholder="John" />
</StackLayout>
<StackLayout>
<Label Text="Last
name"/>
<Entry Placeholder="Doe"/>
</StackLayout>
<StackLayout>
<Label Text="Birthdate"/>
<DatePicker />
</StackLayout>
<StackLayout>
<Label Text="Phone
number"/>
<Entry Placeholder="519 979 1337" Keyboard="Numeric"/>
</StackLayout>
<StackLayout>
<Label Text="Email"/>
<Entry Placeholder="first.last@domain.com" Keyboard="Email"/>
</StackLayout>
</StackLayout>
</ContentPage>
notice that our textbox's have what appears to be a margin, this is because each platform renders them slightly differently, the best solution for this is to create a custom render, a bit involved but MSDN has a great article on just that for entry controls; for now we'll turn a blind eye to that design offence.
let's focus on another issue, and that is our device's orientation. when looking at the horizontal orientation of our app we see that there's a lot of wasted vertical space, we really don't need our labels to be above their textboxs but could in fact just be to the left of them. Also not that the color choice for our labels isn't the greatest.
<?xml
version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="pav.LayoutsExample.MainPage">
<ContentPage.Resources>
<!--Style to
hook into that we override when device rotates-->
<Style x:Key="InnerStack_Style" TargetType="StackLayout" />
<!--Style
for when the device is vertical-->
<Style x:Key="StackVertical_Style" TargetType="StackLayout">
<Setter Property="Spacing" Value="0"/>
<Setter Property="Orientation" Value="Vertical"/>
</Style>
<!--Style
for when the device is horizontal-->
<Style x:Key="StackHorisontal_Style" TargetType="StackLayout">
<Setter Property="Spacing" Value="0"/>
<Setter Property="Orientation" Value="Horizontal"/>
</Style>
<!--Style
the labels to look better-->
<Style TargetType="Label">
<Setter Property="VerticalTextAlignment" Value="Center"/>
<Setter Property="WidthRequest" Value="100"/>
<Setter Property="TextColor" Value="CornflowerBlue" />
</Style>
</ContentPage.Resources>
<StackLayout Spacing="10" Padding="5" Orientation="Vertical">
<StackLayout Style="{DynamicResource InnerStack_Style}">
<Label Text="First
name" />
<Entry Placeholder="John" HorizontalOptions="FillAndExpand" />
</StackLayout>
<StackLayout Style="{DynamicResource InnerStack_Style}">
<Label Text="Last
name"/>
<Entry Placeholder="Doe" HorizontalOptions="FillAndExpand"/>
</StackLayout>
<StackLayout Style="{DynamicResource InnerStack_Style}">
<Label Text="Birthdate"/>
<DatePicker HorizontalOptions="FillAndExpand"/>
</StackLayout>
<StackLayout Style="{DynamicResource InnerStack_Style}">
<Label Text="Phone
number"/>
<Entry Placeholder="519 979 1337" Keyboard="Numeric" HorizontalOptions="FillAndExpand"/>
</StackLayout>
<StackLayout Style="{DynamicResource InnerStack_Style}">
<Label Text="Email"/>
<Entry Placeholder="first.last@domain.com" Keyboard="Email" HorizontalOptions="FillAndExpand"/>
</StackLayout>
</StackLayout>
</ContentPage>
one other thing that should be called out is notice the HorizontalOptions property set to "FillAndExpand" on all of the entry controls (textboxs), this is because when the orientation is horizontal each control tries to take up as little horizontal space as possible.
Which bears the question, where do we updated our StackLayout_Style? and the answer is in the codebehind.
using Xamarin.Forms;
namespace pav.LayoutsExample
{
public partial class MainPage : ContentPage
{
public MainPage() => InitializeComponent();
protected override void
OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
if (width > height)
//landscape
orientation
this.Resources["InnerStack_Style"] = this.Resources["StackHorisontal_Style"];
else
//portarte
orientation
this.Resources["InnerStack_Style"] = this.Resources["StackVertical_Style"];
}
}
}
now everytime the device's orientation changes the OnSizeAllocated method fires, here we say that if the width is greater than the height then we are in landscape mode, otherwise portrait and we point the InnerStack_Style to the appropriate orientation.
now the finished product looks a bit more refined.