How can I add on-platform parameter into a Xamarin Label? - xamarin

Here's the code I have:
<?xml version="1.0" encoding="utf-8"?>
    <Label xmlns="http://xamarin.com/schemas/2014/forms"
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           xmlns:local="clr-namespace:Japanese;assembly=Japanese"
           x:Class="Japanese.Templates.MessageLabel"
           FontSize="{DynamicResource MessageTextFontSize}"
           TextColor="{DynamicResource FooterTextColor}" />
I would like to make it so that the Property="FontFamily" is set like this:
       
    
<OnPlatform x:TypeArguments="x:String">
<On Platform="iOS" Value="FontAwesome5ProLight" />
   <On Platform="Android" Value="Font Awesome 5 Pro-Light-300.otf#FontAwesome5ProLight" />
</OnPlatform>
but how can I make this into a parameter?

Like this, you can try. The platform syntax has changed in Xamarin.Forms 3.2 (I guess),
<Label xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
x:Class="Japanese.Templates.MessageLabel"
FontSize="{DynamicResource MessageTextFontSize}"
TextColor="{DynamicResource FooterTextColor}">
<Label.FontFamily>
<OnPlatform
x:TypeArguments="x:String"
Android="Font Awesome 5 Pro-Light-300.otf#FontAwesome5ProLight"
iOS="FontAwesome5ProLight" />
</Label.FontFamily>
</Label>
but the old syntax(mentioned in the question) will work as well if you want to use that.

<Label xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
x:Class="Japanese.Templates.MessageLabel"
FontSize="{DynamicResource MessageTextFontSize}"
TextColor="{DynamicResource FooterTextColor}">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="iOS" Value="FontAwesome5ProLight" />
<On Platform="Android" Value="Font Awesome 5 Pro-Light-300.otf#FontAwesome5ProLight" />
</OnPlatform>
</Label.FontFamily>
</Label>
I'm not sure I understood your question properly, but is that what you are looking for ?

for better use define font family in style and apply wherever you want
<OnPlatform x:TypeArguments="x:String" x:Key="MediumFont">
<On Platform="Android" Value="fonts/HKGrotesk_Medium.ttf#HK Grotesk" />
<On Platform="UWP" Value="/Assets/Fonts/HKGrotesk_Medium.ttf#HK Grotesk" />
<On Platform="iOS" Value="HKGrotesk-Medium" />
</OnPlatform>

Add This In App.xaml
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Auction.App">
<Application.Resources>
<ResourceDictionary>
<OnPlatform x:TypeArguments="x:String"
Android="FontAwesome5ProLight.otf#FontAwesome5ProLight"
iOS="FontAwesome5ProLight"
WinPhone="20"
x:Key="FontFamilyName" />
<Style x:Key="labelStyle" TargetType="Label">
<Setter Property="FontFamily" Value="{DynamicResource FontFamilyName}"/>
<Setter Property="FontSize" Value="12" />
<Setter Property="VerticalTextAlignment" Value="Center"/>
<Setter Property="TextColor" Value="#000000"/>
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
Use in Any Page Of Your App
in Xaml
<Label x:Name="Register" Text="Registeration" HorizontalTextAlignment ="Center" FontSize="20" Style="{StaticResource labelStyle}">
<Label.GestureRecognizers >
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" ></TapGestureRecognizer>
</Label.GestureRecognizers>
</Label>
and cs
label.Style = (Style)Application.Current.Resources["labelStyle"];

Related

Xamarin fontawesome icons displayed as square with x

After following some tutorials to include FontAwesome 5 Free in my Xamarin project it always ends up showing as a square with an x inside.
I think this is probably related to my xamarin.forms version (2.3.0.46-pre3) and i can't seem to make it work.
Here's the file names
Build action is set to AndroidAsset and copy if newer and BundleResource for IOS
Xaml where im using them
<?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="TrainInURL.MainPage">
<Grid >
<Image Source="bg_home.png" VerticalOptions="Start" HorizontalOptions="Center"/>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" Margin="10" Padding="10" >
<Label Text="Bienvenid#" TextColor="White" Font="Bold,16"></Label>
<Label Text="" TextColor="White" FontFamily="{StaticResource FontAwesomeSolid}"/>
</StackLayout>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" Margin="10" Padding="10" >
<Label x:Name="txt_Nombre" TextColor="White" Font="Bold,16"></Label>
<Label x:Name="txt_Apellido" TextColor="White" Font="Bold,16"></Label>
<Label x:Name="lblMensaje" HorizontalTextAlignment="Center"></Label>
</StackLayout>
<StackLayout >
</StackLayout>
</StackLayout>
</Grid>
</ContentPage>
App.xaml
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TrainInURL.App">
<Application.Resources>
<ResourceDictionary>
<OnPlatform x:Key="FontAwesomeSolid" x:TypeArguments="x:String"
iOS="Font Awesome 5 Free Solid"
Android="FontAwesomeSolid.ttf#Font Awesome 5 Free Solid" />
<OnPlatform x:Key="FontAwesomeRegular" x:TypeArguments="x:String"
iOS="Font Awesome 5 Free Regular"
Android="FontAwesomeRegular.ttf#Font Awesome 5 Free Regular" />
<OnPlatform x:Key="FontAwesomeBrands" x:TypeArguments="x:String"
iOS="Font Awesome 5 Free Brands"
Android="FontAwesomeBrands.ttf#Font Awesome 5 Free Brands" />
</ResourceDictionary>
<!-- Application resource dictionary -->
</Application.Resources>
</Application>
info.plist
<key>UIAppFonts</key>
<array>
<string>FontAwesomeSolid.ttf</string>
<string>FontAwesomeRegular.ttf</string>
<string>FontAwesomeBrands.ttf</string>
</array>
Is it even possible to use custom fonts with my version? Any help is welcomed
Update 1: Updated to version 2.5.1.527436, same issue
Update 2: Tried using a different font file, seems to indicate it can find the font but can't render it. Using the following font renderer gave the following results
CustomFontRenderer
[assembly: ExportRenderer(typeof(CustomFontLabel), typeof(CustomFontRenderer))]
namespace TrainInURL.Droid
{
public class CustomFontRenderer : LabelRenderer
{
public CustomFontRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
TextView label = (TextView) Control;
if (e.NewElement?.FontFamily != null)
{
Typeface font = null;
// the try-catch block will ensure the element is at least rendered with default
// system font in Xamarin Previewer instead of crashing the view
try
{
font = Typeface.CreateFromAsset(Android.App.Application.Context.Assets, e.NewElement.FontFamily);
}
catch (Exception)
{
font = Typeface.Default;
}
label.Typeface = font;
}
}
}
}
Xaml
<StackLayout Orientation="Horizontal" Margin="10" Padding="10" >
<Label Text="Bienvenid#" TextColor="White" FontSize="16" FontAttributes="Bold"></Label>
<Label Text="" TextColor="White" FontFamily="{StaticResource FontAwesomeSolid}"/>
<Label Text="" TextColor="White" FontFamily="{StaticResource FontAwesomeBrands}"/>
<Label Text="" TextColor="White" FontFamily="{StaticResource FontAwesomeRegular}"/>
<trainInUrl:CustomFontLabel Text="" FontFamily="{StaticResource FontAwesomeSolid}"/>
<trainInUrl:CustomFontLabel Text="" FontFamily="{StaticResource FontAwesomeBrands}"/>
<trainInUrl:CustomFontLabel Text="" FontFamily="{StaticResource FontAwesomeRegular}"/>
</StackLayout>
Result
I followed the instructions found here which got me started. there was also a bit of further tweaking to completely get it working (particularly UWP). I do note you are using the .ttf files and I am using the .otf files, which could be an issue.
My final final assets folder and resource implementation are below (android - no IOS here), hopefully helps you out.
<Application.Resources>
<ResourceDictionary>
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeBrands">
<On Platform="Android" Value="FontAwesome5Brands400.otf#Regular"/>
<On Platform="UWP" Value="/Assets/Fonts/FontAwesome5Brands400.otf#Font Awesome 5 Brands"/>
</OnPlatform>
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeSolid">
<On Platform="Android" Value="FontAwesome5Solid900.otf#Regular"/>
<On Platform="UWP" Value="/Assets/Fonts/FontAwesome5Solid900.otf#Font Awesome 5 Free"/>
</OnPlatform>
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeRegular">
<On Platform="Android" Value="FontAwesome5Regular400.otf#Regular"/>
<On Platform="UWP" Value="/Assets/Fonts/FontAwesome5Regular400.otf#Font Awesome 5 Free"/>
</OnPlatform>
</ResourceDictionary>
</Application.Resources>
Updated the app to version 4.4 and that solved the issue

Xamarin Forms - center title in a stacklayout

The screenshot below shows a header that includes a hamburger menu and a title. Notice how the title is centered on it's bounding area (the red box). How can I get the title to center on the width of the phone, but leave the hamburger menu where it is?
Here is the code that creates the header area...
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WP.MobileMidstream.Device.Pages.RunSheetHeader">
<ContentView.Resources>
<Style x:Key="HeaderStyle" TargetType="StackLayout">
<Setter Property="BackgroundColor" Value="#00458C" />
</Style>
</ContentView.Resources>
<ContentView.Content>
<StackLayout Orientation="Horizontal"
HorizontalOptions="FillAndExpand"
Style="{StaticResource HeaderStyle}">
<StackLayout.HeightRequest>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS">80</On>
<On Platform="Android">56</On>
</OnPlatform>
</StackLayout.HeightRequest>
<Image Source="hamburger_icon"
Margin="10" />
<Label VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
HorizontalOptions="FillAndExpand"
FontSize="20"
BackgroundColor="Red"
TextColor="White">Daily Run Sheet</Label>
</StackLayout>
</ContentView.Content>
</ContentView>
#Jason suggested a Grid instead of the StackLayout. Here is what I came up with that works. Thanks #Jason!
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WP.MobileMidstream.Device.Pages.RunSheetHeader">
<ContentView.Resources>
<Style x:Key="HeaderStyle" TargetType="Grid">
<Setter Property="BackgroundColor" Value="#00458C" />
</Style>
</ContentView.Resources>
<ContentView.Content>
<Grid Style="{StaticResource HeaderStyle}">
<Grid.RowDefinitions>
<RowDefinition>
<RowDefinition.Height>
<OnPlatform x:TypeArguments="GridLength">
<On Platform="iOS">80</On>
<On Platform="Android">56</On>
</OnPlatform>
</RowDefinition.Height>
</RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
HorizontalOptions="Fill"
FontSize="20"
TextColor="White">Daily Run Sheet</Label>
<Image Source="hamburger_icon"
Grid.Row="0"
Grid.Column="0"
Margin="10" />
</Grid>
</ContentView.Content>
</ContentView>

Multi Data Trigger In Xamarin Forms

I am attempting to allow click on my button ONLY if the two text fields are not null. However, I am getting the compile error of
Type multi-data trigger not found
Below is my syntax, how should I change it so it executes as desired?
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" >
<ContentPage.Content>
<StackLayout Orientation="Vertical" Padding="30" Spacing="40">
<BoxView HeightRequest="10"/>
<Frame BackgroundColor="#BF043055" HasShadow="False">
<StackLayout Orientation="Vertical" Spacing="10">
<Entry x:Name="Email" Text="{Binding Email}" Placeholder="Email"
PlaceholderColor="Red" HeightRequest="50"
Keyboard="Email" TextColor="Black" />
<Entry x:Name="Password" Text="{Binding Password}" Placeholder="Password"
PlaceholderColor="Red" HeightRequest="50"
IsPassword="True" TextColor="Black" />
</StackLayout>
</Frame>
<Button x:Name="loginbutton" Command="{Binding SubmitCommand}" Text="Login" TextColor="White"
FontAttributes="Bold" FontSize="Large" HorizontalOptions="FillAndExpand"
BackgroundColor="#088da5" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Email, Path=Text.Length, Mode=OneWay}" Value="0"/>
<Condition Binding="{Binding ElementName=Password, Path=Text.Length, Mode=OneWay}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackLayout>
</ContentPage.Content>
</ContentPage>
EDIT
I edited my syntax to the below but I am getting a compile error of:
No property, bindable property, or event found for 'ElementName', or mismatching type between value and property.
<Button x:Name="loginbutton" Command="{Binding SubmitCommand}" Text="Login" TextColor="White"
FontAttributes="Bold" FontSize="Large" HorizontalOptions="FillAndExpand"
BackgroundColor="#088da5" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<MultiTrigger TargetType="{x:Type Button}">
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Email, Path=Text.Length, Mode=OneWay}" Value="0"/>
<Condition Binding="{Binding ElementName=Password, Path=Text.Length, Mode=OneWay}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
MultiDataTrigger is specific to WPF. Xamarin uses MultiTrigger, which essentially does the same thing. Have a look through this blog post to see how to implement Triggers in Xamarin Forms.

How can I access a resource when it's declared as a Class in C# back end?

My main resources look like this:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:converters="clr-namespace:Japanese"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Japanese.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary Source="/Resources/DetailRes.xaml" />
I have this resource file:
<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Japanese.DetailRes">
<Style x:Key="DetailLabel" TargetType="Label">
<Setter Property="FontSize">
<Setter.Value>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS" Value="35" />
<On Platform="Android" Value="35" />
</OnPlatform>
</Setter.Value>
</Setter>
<Setter Property="VerticalOptions" Value="Center" />
<Setter Property="LineBreakMode" Value="WordWrap" />
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
</ResourceDictionary>
In XAML I access it like this:
<t:BaseFrameButtonTemplate xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:t="clr-namespace:Japanese.Templates"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
x:Class="Japanese.Templates.RoundButtonText" x:Name="this" >
<Label Text="{Binding Text, Source={x:Reference this}}"
Style="{StaticResource DetailRes}"
x:Name="Label" />
</t:BaseFrameButtonTemplate>
I would like to access this in C# but do not know how to do it. I tried this but it does not find the resource:
Label.Style = (Style)Application.Current.Resources["DetailRes"];
You can use the TryGetValue to obtain a single from your ResourceDictionary:
if (Application.Current.Resources.TryGetValue("DetailLabel", out object style))
{
someLabel.Style = (Style)style;
}

Image background not showed correctly for ListView

I have a xaml page to show a label and a listview with grouping option. There is a background image to be shown for the whole page as I expect. However, the page works well with Android simulator (the image background is displayed on the whole page) but not with iOS simulator. on the iOS simulator, the image background is showed under the top label element with text of "History Facts", but it is not seen under the ListView area I marked/painted inside a red frame. The white background is filled under the ListView instead. Please see the attached screen shot. Please help. Thanks.
My xaml file markups:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Quiz;assembly=Quiz"
xmlns:converter="clr-namespace:Quiz.Converters;assembly=Quiz"
x:Class="Quiz.QuizResultPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="10, 20, 10, 0" Android="10, 0" WinPhone="10, 0" />
</ContentPage.Padding>
<ContentPage.Resources>
<ResourceDictionary>
<converter:BoolToStringConverter x:Key="boolToString" TrueText="Yes" FalseText="No" />
<converter:BoolToColorConverter x:Key="boolToColor" TrueColor="Green" FalseColor="Red"/>
<Style TargetType="View" x:Key="labelBase">
<Setter Property="HorizontalOptions" Value="Center"></Setter>
<Setter Property="VerticalOptions" Value="Center"></Setter>
</Style>
<Style TargetType="Label" x:Key="labelTopTitleStyle" BasedOn="{StaticResource labelBase}">
<Setter Property="FontSize" Value="Large"></Setter>
</Style>
<Style TargetType="Label" x:Key="questionStyle">
<Setter Property="FontFamily" Value="Courgette-Regular"></Setter>
<Setter Property="TextColor" Value="White"></Setter>
<Setter Property="FontAttributes" Value="Bold"></Setter>
<Setter Property="FontSize" Value="Medium"></Setter>
</Style>
<Style TargetType="Label" x:Key="labelTimerStyle" BasedOn="{x:StaticResource labelBase}">
<Setter Property="TextColor" Value="Yellow"></Setter>
<Setter Property="FontAttributes" Value="Bold"></Setter>
<Setter Property="FontSize" Value="Medium"></Setter>
<Setter Property="BackgroundColor" Value="Olive"></Setter>
</Style>
<Style x:Key="styleAnswer" TargetType="Label">
<Setter Property="FontFamily" Value="Courgette-Regular"></Setter>
<Setter Property="FontSize" Value="Large"></Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<RelativeLayout Padding="0">
<!-- Background -->
<Image x:Name="imgBG"
Aspect="AspectFill"
Opacity="0.2"
Source="{local:ImageResource Quiz.Images.bg8.jpg}"
RelativeLayout.WidthConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.HeightConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Height}">
</Image>
<StackLayout RelativeLayout.WidthConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.HeightConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Height}"
Orientation="Vertical">
<Label Text="History Facts" Style="{Binding Source={x:StaticResource labelTopTitleStyle}}" ></Label>
<ListView x:Name="listViewResultQuestions" BindingContext="{Binding}" ItemsSource="{Binding Questions}"
IsGroupingEnabled="True"
GroupDisplayBinding="{Binding Text}"
GroupShortNameBinding="{Binding ShortName}"
>
<ListView.RowHeight>
<OnPlatform x:TypeArguments="x:Int32" iOS="80" Android="80" WinPhone="90" />
</ListView.RowHeight>
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BindingContext="{Binding}" VerticalOptions="FillAndExpand" Padding="5"
BackgroundColor="{Binding Path=IsAnswerValid, Converter={x:StaticResource boolToColor}}" Orientation="Horizontal">
<Label Text="{Binding DisplayIndex, StringFormat='{0}. '}" Style="{StaticResource questionStyle}" LineBreakMode="NoWrap"/>
<Label Text="{Binding Text}" Style="{StaticResource questionStyle}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BindingContext="{Binding}" Padding="20, 5, 5, 5" Orientation="Vertical">
<Label Text="{Binding Text}" Style="{StaticResource styleAnswer}"/>
<Label Text="{Binding IsValid, StringFormat='Answer is correct: {0}', Converter={x:StaticResource boolToString}}" Style="{StaticResource styleAnswer}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</RelativeLayout>
</ContentPage>
On iOS the listview has a white background color as default , so all what you need to do is to Set the BackgroundColor to "Transparent" and this will solve your problem
Following BraveHeart, I need to set the BackgroundColor of the ListView to "Transparent" and the problem has been solved.

Resources