FontFamily defined in XAML per platform - xaml

In my Xamarin Forms project I would like to define the Form family onect per platform and the use that in the application.
So far I've hardcoded the FontFamily per controltype
<Style x:Key="TahomaBase_Label" TargetType="Label" BaseResourceKey="SubtitleStyle">
<Setter Property="FontFamily" Value="Tahoma" />
...
</Style>
Is it posible to set Fotnfamily globally in my XAML code preferable itn a OnPlatform tag?

Define a style in the App.xaml and then reference that style throughout the app. That way you can set the font once in the App.xaml using the OnPlatform tag and never have to worry about OnPlatform in all your other XAML files.
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="PlatformFontSample.App">
<Application.Resources>
<ResourceDictionary>
<OnPlatform x:Key="FontFamilyName" x:TypeArguments="x:String" iOS="MarkerFelt-Thin" Android="OpenSans" WinPhone="Segoe UI" />
<Style x:Key="FontLabel" TargetType="Label">
<Setter Property="FontFamily" Value="{DynamicResource FontFamilyName}" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
And then:
<Label Text="{Binding Name}" Style="{DynamicResource FontLabel}" FontSize="Medium" FontAttributes="Bold" LineBreakMode="NoWrap"/>

Related

ResourceDictionary: System.InvalidCastException

I get an Exception throw and I cant figure out why. My guess is that Im overlooking something simple. The Exception gets thrown in ResourceSharingPage.xaml.g.cs
this is my xaml:
<?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="BookCodedotNet2.ResourceSharingPage">
<ContentPage.Resources>
<ResourceDictionary>
<x:String x:Key="fontSize">Large</x:String>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Button Text=" Carpe diem ">
<Button.FontSize>
<StaticResourceExtension Key="fontSize"/>
</Button.FontSize>
</Button>
</StackLayout>
</ContentPage>
If I remove
<Button.FontSize>
<StaticResourceExtension Key="fontSize"/>
</Button.FontSize>
I can build the app.
In the resources, try something like below. Use double value instead of string as FontSize is a double.
<ResourceDictionary>
<x:Double x:Key="fontSize">35</x:Double>
</ResourceDictionary>
You've defined the resource of type x:String. FontSize doesn't accept values of type String. It only accepts values of type Double or NamedSize. As you mentioned in the comment to Abdul Gani's answer, you should be defining NamedSize.
You are better off using the Style tag and setting the style of your Label that way. Follow SushiHangover's answer over here if you want to use Style instead.
You can use NamedSize in resource dictionary in this way:
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="fontSize" TargetType="Button">
<Setter Property="FontSize" Value="Large" />
</Style>
<Color x:Key="NormalTextColor">Blue</Color>
<Style x:Key="MediumBoldText" TargetType="Button">
<Setter Property="FontSize" Value="Large" />
<Setter Property="FontAttributes" Value="Bold" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Button Text=" Carpe diem " Style="{StaticResource fontSize}"> </Button>
<Button Text="Test"
TextColor="{StaticResource NormalTextColor}"
Style="{StaticResource MediumBoldText}" />
</StackLayout>

UWP Global Resources is overriden by Local Resources even if not the same property

I have an application resource defined in App.xaml. It is tested that the resource applies to the local style if no local resource is defined. So this not some issue like "resource not being initialized".
The code is as below.
App.xaml
<Application
...omitted
RequestedTheme="Light">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Style/DefaultTheme.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
DefaultTheme.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Button">
<Setter Property="FontSize" Value="50" />
<Setter Property="Background" Value="Red" />
</Style>
</ResourceDictionary>
MainPage.xaml
...omitted
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="100" />
<Setter Property="VerticalAlignment" Value="Stretch" />
</Style>
</StackPanel.Resources>
<Button Content="Hello" />
<Button Content="Happy" />
<Button Content="World" />
</StackPanel>
You can see that from the StackPanel's local resources. It is only setting Width and VerticalAlignment while the global dictionary is assigning FontSize and Background. There is no contradiction.
I have also tried this syntax in Xamarin Forms XAML. The local resource will only override global resource when they are assigning the same property. Global resources still apply to the element if not specified.
For more information, ReSharper is having a nice icon saying this "Hides resource from DefaultTheme.xaml ". But when I do this in Xamarin Forms, it will fade out only the properties that are being overridden.
Is there a way to make local resources an add on to global resources in UWP? Assigning x:Key to the global resource then add BasedOn will not be a solution. As I don't think making every button in the app having to derive the global resource make sense in theming.

Xamarin.Forms setting specific style for platform

I'm trying to style my UWP application with some specific styles, while on other platforms it should remain default.
This is my project layout:
I tried the following things:
In Clients.Shared creating a style as following:
<Style x:Key="SomeStyle" TargetType="Button" />
And adding the same Style key in the Clients.Themes.UWP so it could hopefully override it, but no luck.
Then I tried Having a Dummy Style and using the onPlatform but that didn't work either, but I still think this is the way to go. I had the following code:
<Style x:Key="DummyStyle" TargetType="Button">
<Setter Property="Style">
<Setter.Value>
<OnPlatform x:Key="ButtonStyle" x:TypeArguments="Style">
<On Platform="UWP" Value="{StaticResource SomeStyle}"></On>
</OnPlatform>
</Setter.Value>
</Setter>
</Style>
I tried messing around with merged ResourceDictionary.MergedDictionaries but there I couldn't include the xaml
Anybody have any clue?
Try this:
<OnPlatform x:TypeArguments="Color" Android="Green" iOS="White" WinPhone="White"
x:Key="PrimaryColor" />
<Style x:Key="ButtonColor" TargetType="Button">
<Setter Property="BackgroundColor" Value="{StaticResource PrimaryColor}" />
</Style>
<Button Text="Hello" HorizontalOptions="StartAndExpand"
Grid.Row="2" Grid.ColumnSpan="2" Style="{StaticResource ButtonColor}" />
In this example, I am defining a style for a Button called ButtonColor. This Button will use a BackgroundColor of white for all platforms except Android where it will be Green.
I find this is the most common use for this tag with regard to styling; if you are working with fonts, be sure to run on simulator and actual devices to get the font that you want.
This syntax works for me:
<Style x:Key="zoneLabelStyle" TargetType="Label">
<Setter Property="HeightRequest" Value="18" />
<Setter Property="Margin">
<OnPlatform x:TypeArguments="Thickness">
<On Platform="Android" Value="0, -3, 0, 0" />
</OnPlatform>
</Setter>
</Style>
Why do not use
<Button.Style>
<OnPlatform x:TypeArguments="x:Style">
<OnPlatform.iOS>...</OnPlatform.iOS>
<OnPlatform.Android>...</OnPlatform.Android>
<OnPlatform.WinPhone>...</OnPlatform.WinPhone>
</OnPlatform>
</Button.Style>
Hope it will help.

How to call a Style in a ResourceDictionary file in XAML?

I have a button style in a created style.xaml ResourceDictionary file.
I used this code to call it:
<Button Style="{DynamicResource exitButton}" />
But it didn't recognize the style key either using StaticResource doesn't work too. How to solve this problem?
My style code:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="exitButton" TargetType="Button">
<Setter Property="Width" Value="22"/>
<Setter Property="Height" Value="32"/>
<Setter Property="Background" Value="#FF7070"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock Text="X"
FontSize="15"
Foreground="White"
FontWeight="Bold"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
You have to import the ResourceDictionary file in your xaml, in the Resources tags.
Something like this:
<UserControl blablabla...>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/*PROJECT_NAME*;component/*FOLDER_PATH*/style.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</USerControl.Resources>
<!-- the content -->
...
<Button Style="{StaticResource exitButton}"/>
</UserControl>
You have two options:
As HasNotifications said, embede the resource into the view that you want the style take affect
Embed the style to the application ResourceDictionary. On that case the style will be available to any view on the application
Add the following code to the App.xaml file:
<Application x:Class="WpfApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/*PROJECT_NAME*;component/*FOLDER_PATH*/style.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

Xaml Style Child Control in Universal Windows Platform (UWP)

I would like to know how to set style targetting child controls on the UWP within a style definition.
WPF seems to have 'Style.Resources' to define sub-styles but this doesn't seem the case for UWP
example in wpf : WPF - How to create a style that applies styles to child types
If you want the styles in separate sheets ( which you should. I showed the Styles in the control itself because I misread and thought that's what you wanted ) you can create a Resources folder and add different ResourceDictionaries. Personally I usually create a separate dictionary for Brushes, Styles, Templates, and Converters. Then you declare them in the ResourceDictionary.MergedDictionaries in App.xaml
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
RequestedTheme="Light">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Brushes.xaml" />
<ResourceDictionary Source="/Resources/Styles.xaml" />
<ResourceDictionary Source="/Resources/Converters.xaml" />
<ResourceDictionary Source="/Resources/Templates.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
You can define Styles in the ResourceDictionary of the parent control. The Style defined in Window.Resources applies to all Rectangles because it doesn't specify a Key, so the Rectangle in the first StackPanel is yellow and small. The second StackPanel defines it's own Resources, which its children use, and they end up different colors and a larger size. There's also Style inheritance in there using BasedOn
<Window x:Class="GBTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-GBTest"
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525">
<!--Default style defined in the Window Resources-->
<Window.Resources>
<Style TargetType="Rectangle">
<Setter Property="Width"
Value="100" />
<Setter Property="Height" Value="100" />
<Setter Property="Fill"
Value="Yellow" />
</Style>
</Window.Resources>
<StackPanel>
<Rectangle />
<StackPanel>
<!--The styles defined in the resources of this StckPanel will apply to its children, overriding the default style defined in the Window Resources-->
<StackPanel.Resources>
<Style TargetType="Rectangle"
x:Key="BigStyle">
<Setter Property="Height"
Value="200" />
<Setter Property="Width"
Value="200" />
</Style>
<Style TargetType="Rectangle"
x:Key="RedStyle"
BasedOn="{StaticResource BigStyle}">
<Setter Property="Fill"
Value="Red" />
</Style>
<Style TargetType="Rectangle"
BasedOn="{StaticResource BigStyle}"
x:Key="BlueStyle">
<Setter Property="Fill"
Value="Blue" />
</Style>
</StackPanel.Resources>
<Rectangle Style="{StaticResource RedStyle}" />
<Rectangle Style="{StaticResource BlueStyle}" />
</StackPanel>
</StackPanel>