使用Xamarin.Forms中的View Model属性绑定到StaticResource?

时间:2018-09-04 11:23:20

标签: c# android xaml mvvm xamarin.forms

我在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在运行时切换自定义字体的方法?

3 个答案:

答案 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)

https://blog.xamarin.com/triggers-in-xamarin-forms/中所述,

数据触发器是必经之路。按照那里的示例,现在我有了:

                    <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>