【问题标题】:Binding to StaticResource with a property of View Model in Xamarin.Forms?在 Xamarin.Forms 中使用 View Model 的属性绑定到 StaticResource?
【发布时间】:2018-09-04 11:23:19
【问题描述】:

我在 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 Model 中的一个属性。 我试过了:

FontFamily="{Binding CurrentFontFamily}"

CurrentFontFamily 的值可以指向现有的系统字体,但我想指向一个自定义字体,指向 ResourceDictionary 中定义的字体。

然后我试过了:

FontFamily="{StaticResource {Binding CurrentFontFamily}}"

对于这种化妆语法显然存在运行时错误。我只是想知道 XAML 中是否有通过 MVVM 视图模型在运行时切换自定义字体?

【问题讨论】:

  • 我没有尝试过,但DynamicResource 可能会在这种情况下工作,而不是StaticResource

标签: c# android xaml mvvm xamarin.forms


【解决方案1】:

你试过了吗?

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

【讨论】:

  • 正如我在 OP 中提到的,这不是我想要的,因为它指向一个具体的字体名称,而不是 ResourceDctionary 中定义的自定义字体。所以基本上我希望绑定点到资源的键。
【解决方案2】:

数据触发器是要走的路,如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>

【讨论】:

    【解决方案3】:

    XAML 中的FontFamily="{Binding CurrentFontFamily}" 是您必须采用的方式。但是,CurrentFontFamily 属性没有理由必须指向系统字体。 Xamarin.Forms FontFamily 属性只是一个字符串,因此您没有理由不能执行以下操作:

    // previous code...
    CurrentFontFamily = (whateverCondition == something)
        ? (string)Application.Current.Resources["SuperFont"]
        : (string)Application.Current.Resources["NormalFont"];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-28
      • 1970-01-01
      • 2018-09-12
      • 2014-11-12
      • 2010-10-16
      • 2020-03-25
      • 1970-01-01
      相关资源
      最近更新 更多