I have some custom fonts defined in ResourceDictionary
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Fonlow.VA.App">
<Application.Resources>
<ResourceDictionary>
<OnPlatform x:TypeArguments="x:String" x:Key="SuperFont">
<On Platform="Android" Value="Super.ttf#Super" />
<On Platform="UWP" Value="/Assets/Super.ttf#Super" />
<!--<On Platform="iOS" Value="OpenSans-Bold" />-->
</OnPlatform>
<OnPlatform x:TypeArguments="x:String" x:Key="NormalFont">
<On Platform="Android" Value="Normal.ttf#Normal" />
<On Platform="UWP" Value="/Assets/Normal.ttf#Normal" />
<!--<On Platform="iOS" Value="OpenSans-Bold" />-->
</OnPlatform>
</ResourceDictionary>
</Application.Resources>
And
<Label Text="{Binding CurrentOptotype.Text}" FontFamily="{StaticResource SuperFont}" FontSize="{Binding CurrentFontSize}" TextColor="Black" />
So far so good. However, I would switch the FontFamily at runtime through ViewModel binding just like the binding for FontSize, since CurrentFontSize is a property in the View Model. I had tried:
FontFamily="{Binding CurrentFontFamily}"
And the value of CurrentFontFamily can point to an existing system font, but I want to point to a custom font pointing to what defined in ResourceDictionary.
I had then tried:
FontFamily="{StaticResource {Binding CurrentFontFamily}}"
And there's runtime error obviously against such makeup syntax. I just wonder whether there's a in XAML to switch custom font at runtime through MVVM View Model?
Have you tried this?
FontFamily="{Binding CurrentFontFamily}"
Edit:
You can do this with a converter :
public class FontConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var fontName = value as string;
if(!Application.Current.Resources.ContainsKey(fontName))
throw new KeyNotFoundException($"{fontName} not found in resources");
return (string) Application.Current.Resources[fontName];
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
In your App.xaml, add your converter :
<Application.Resources>
<ResourceDictionary>
....
<extensions:FontConverter x:Key="FontConverter"/>
</ResourceDictionary>
</Application.Resources>
Then you can bind your property
FontFamily={Binding FontName, Converter={StaticResource FontConverter}}
Data Trigger is the way to go, as explained in https://blog.xamarin.com/triggers-in-xamarin-forms/. Following the example there, now I have:
<Label Text="{Binding CurrentText}" Grid.Column="1" Margin="5,0,0,0"
FontSize="{Binding CurrentFontSize}" TextColor="Black"
HorizontalTextAlignment="Start" VerticalTextAlignment="Center">
<Label.Triggers>
<DataTrigger TargetType="Label"
Binding="{Binding Source={x:Reference fontSelected}, Path=SelectedIndex}"
Value="0">
<Setter Property="FontFamily" Value="{StaticResource NormalFont}"/>
</DataTrigger>
<DataTrigger TargetType="Label"
Binding="{Binding Source={x:Reference chartSelected}, Path=SelectedIndex}"
Value="1">
<Setter Property="FontFamily" Value="{StaticResource SuperFont}"/>
</DataTrigger>
</Label.Triggers>
</Label>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With