我在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>
和
<Label Text="{Binding CurrentOptotype.Text}" FontFamily="{StaticResource SuperFont}" FontSize="{Binding CurrentFontSize}" TextColor="Black" />
到目前为止,一切都很好。但是,我将在运行时通过ViewModel绑定切换FontFamily,就像FontSize的绑定一样,因为CurrentFontSize是View模型中的一个属性。 我尝试过:
FontFamily="{Binding CurrentFontFamily}"
并且CurrentFontFamily的值可以指向现有的系统字体,但是我想指向一个自定义字体,该字体指向ResourceDictionary中定义的字体。
然后我尝试了:
FontFamily="{StaticResource {Binding CurrentFontFamily}}"
显然,针对这种构成语法存在运行时错误。我只是想知道XAML中是否存在通过MVVM View Model在运行时切换自定义字体的方法?
答案 0 :(得分:2)
您尝试过吗?
FontFamily="{Binding CurrentFontFamily}"
编辑:
您可以使用转换器:
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();
}
}
在您的App.xaml中,添加您的转换器:
<Application.Resources>
<ResourceDictionary>
....
<extensions:FontConverter x:Key="FontConverter"/>
</ResourceDictionary>
</Application.Resources>
然后您可以绑定财产
FontFamily={Binding FontName, Converter={StaticResource FontConverter}}
答案 1 :(得分:0)
XAML中的FontFamily="{Binding CurrentFontFamily}"
是您将不得不使用的方法。但是,没有任何理由CurrentFontFamily
属性必须指向系统字体。 Xamarin.Forms FontFamily属性只是一个字符串,因此没有理由您不应该执行以下操作:
// previous code...
CurrentFontFamily = (whateverCondition == something)
? (string)Application.Current.Resources["SuperFont"]
: (string)Application.Current.Resources["NormalFont"];
答案 2 :(得分:0)
数据触发器是必经之路。按照那里的示例,现在我有了:
<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>