If you are a bit advanced with Xamarin, you should already now that there is a possibility of styling your controls almost like in WPF.
Almost, because there is a few strange bugs involving this. For example, there is a problem with styling a Padding property in Frame. Consider the following XAML of Xamarin application (I tested it in Android):
="1.0"="utf-8"
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:styles="clr-namespace:Styles;assembly=Styles"
x:Class="Styles.App">
<Application.Resources>
<ResourceDictionary>
<Style TargetType="Frame" x:Key="Style">
<Setter Property="Padding" Value="0" />
</Style>
</ResourceDictionary>
</Application.Resources>
<Application.MainPage>
<ContentPage>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="100" />
<RowDefinition Height="100" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Frame VerticalOptions="Center"
Grid.Row="0"
Padding="0">
<Label Text="100 height" FontSize="60" />
</Frame>
<Frame VerticalOptions="Center" Style="{StaticResource Style}"
Grid.Row="1"
Padding="0">
<Label Text="100 height" FontSize="60" />
</Frame>
<Frame VerticalOptions="Center" Style="{StaticResource Style}"
Grid.Row="2">
<Label Text="100 height" FontSize="60" />
</Frame>
</Grid>
</ContentPage>
</Application.MainPage>
</Application>
It is almost the same as default (created by template) shared application - but instead of App.cs, we have a more advanced XAML file.
What not suspecting (or better: excepting a normal behavior) user would except all Frames to have the same view because properties will have the same values. Should have the same values, but they are not. This code will produce the following layout:
Last Frame does not have explicit setting for Padding in its declaration and this property is resolved to default value and its contents just do not fit in the available space. Why? There is a bug for that.
But according to comments, Xamarin Team is not exactly willing to fix it.
Fortunately, there is a quick workaround for that. The easiest thing to do is to just add this method to a new class named i.e. FixedFrame
:
public class ExtendedFrame : Frame
{
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == StyleProperty.PropertyName)
{
if (Style.Setters.Any(s => s.Property == PaddingProperty))
{
Padding = (Thickness)Style.Setters.First(s => s.Property == PaddingProperty).Value;
}
}
}
}
Using this class instead of original Frame from Xamarin framework will ensure proper Padding value after applying Style to FixedFrame
control. Consider changed above Android application, with added new FixedFrame
control at the end. Only property set is Style
and there is no explicit value for Padding in control declaration:
="1.0"="utf-8"
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:styles="clr-namespace:Styles;assembly=Styles"
x:Class="Styles.App">
<Application.Resources>
<ResourceDictionary>
<Style TargetType="Frame" x:Key="Style">
<Setter Property="Padding" Value="0" />
</Style>
</ResourceDictionary>
</Application.Resources>
<Application.MainPage>
<ContentPage>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="100" />
<RowDefinition Height="100" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Frame VerticalOptions="Center"
Grid.Row="0"
Padding="0">
<Label Text="100 height" FontSize="60" />
</Frame>
<Frame VerticalOptions="Center" Style="{StaticResource Style}"
Grid.Row="1"
Padding="0">
<Label Text="100 height" FontSize="60" />
</Frame>
<Frame VerticalOptions="Center" Style="{StaticResource Style}"
Grid.Row="2">
<Label Text="100 height" FontSize="60" />
</Frame>
<styles:FrameExt VerticalOptions="Center" Style="{StaticResource Style}"
Grid.Row="3">
<Label Text="100 height" FontSize="60" />
</styles:FrameExt>
</Grid>
</ContentPage>
</Application.MainPage>
</Application>
As a result, we will have the following window layout:
As you see, the last row with FixedFrame
control has proper Padding property value.
Simple and effective. See the link at the top of this post for a sample application.