如何将StaticResource的名称绑定到ViewModel属性?

时间:2019-11-30 01:32:41

标签: xamarin mvvm xamarin.forms

我有一个Xamarin标签显示ttf文件中的图标的情况。按原样,标签看起来如下。

<Label
Text="{StaticResource Account}"/>

帐户是我的Styles.xaml文件中的一个字符串,用于定义十六进制值。

<x:String x:Key="Account">&#xe70e;</x:String>

以上工作正常。但是,我想通过ViewModel中的属性绑定Icon文本名称。以下内容不起作用,但我在想这样的事情:

 Text="{StaticResource Binding=IconName}"

我该怎么做?

更新:向此问题添加更多上下文。

在我的Styles.xaml中,我定义了一个对应于其十六进制值的字典

<x:String x:Key="Back">&#xe709;</x:String>
<x:String x:Key="Share">&#xe704;</x:String>
<x:String x:Key="Next">&#xe71a;</x:String>
<x:String x:Key="Account">&#xe70e;</x:String>
<x:String x:Key="Bell">&#xe700;</x:String>
<x:String x:Key="Mail">&#xe70e;</x:String>
<x:String x:Key="Help">&#xe72c;</x:String>

此样式文件是我的xaml文件的资源。

        <ContentPage.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Styles.xaml" />
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </ContentPage.Resources>

在我的XAML文件中,我正在迭代以显示不同的图标。

            <StackLayout
                x:Name="ItemsList"
                Grid.Row="1"
                BindableLayout.ItemsSource="{Binding MenuItems}">
                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <StackLayout>
                            <Label  Text="{StaticResource Account}" FontFamily="{StaticResource FontIcons}"
                                FontSize="Large"></Label>
                        </StackLayout>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </StackLayout>

在我的列表中,我指定了图标名​​称。

        MenuItems = new List<AppMenuItem>()
        {
            new AppMenuItem()
            {
                Title = "View A",
                IconSource = "Account",
            },
            new AppMenuItem()
            {
                Title = "View B",
                IconSource = "Mail",
            }

        };

更新2:我正在尝试构建一个值转换器,但似乎无法访问合并的字典。我正在使用:

Application.Current.Resources.TryGetValue(value.ToString(),输出为var retValue);

retValue始终返回NULL。

4 个答案:

答案 0 :(得分:0)

您可以绑定标签样式。

<Style TargetType="Label">
    <Setter Property="Text" Value="{Binding Account}"/>
</Style>

答案 1 :(得分:0)

    -----:::App.xaml:::------
 <?xml version="1.0" encoding="utf-8" ?>
    <Application xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="PracticeXamarinForms.App">
        <Application.Resources>
            <ResourceDictionary>
                <x:String x:Key="Back">&#xe709;</x:String>
                <x:String x:Key="Share">&#xe704;</x:String>
                <x:String x:Key="Next">&#xe71a;</x:String>
                <x:String x:Key="Account">&#xe70e;</x:String>
                <x:String x:Key="Bell">&#xe700;</x:String>
                <x:String x:Key="Mail">&#xe70e;</x:String>
                <x:String x:Key="Help">&#xe72c;</x:String>
            </ResourceDictionary>
        </Application.Resources>
    </Application>

    -----:::Views:::------
    <?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="PracticeXamarinForms.Views.DemoPage"
                 xmlns:vm="clr-namespace:PracticeXamarinForms.ViewModels">
        <ContentPage.BindingContext>
            <vm:DemoViewModel/>
        </ContentPage.BindingContext>
        <ContentPage.Content>
            <StackLayout>
                <Label 
                    VerticalOptions="CenterAndExpand" 
                    HorizontalOptions="CenterAndExpand"
                       Text="{Binding IconName}"/>
            </StackLayout>
        </ContentPage.Content>
    </ContentPage>

    -----:::ViewModels:::------
    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace PracticeXamarinForms.ViewModels
    {
        public class DemoViewModel
        {
            #region properties
            public string IconName { get; set; }
            #endregion

            public DemoViewModel()
            {
                IconName = (string)App.Current.Resources["Mail"];
            }
        }
    }

答案 2 :(得分:0)

定义图标字形的类:

namespace MyNamespace
{
    public static class Icons
    {
        public const string Glyph = "\ue000";
        ...
    }
}

资源字典/Resources/Glyphs.xaml

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    xmlns:i="clr-namespace:MyNamespace">

    <OnPlatform x:Key="Glyph" x:TypeArguments="x:String" Default="{x:Static i:Icons.Glyph}" />

</ResourceDictionary>

页面上的参考资源字典:

<ResourceDictionary>
  <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="/Resources/Glyphs.xaml" />
  </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

ViewModel示例:

using MyNamespace;
...
public class FontViewModel
{
    public string GlyphFromClass { get; set; }

    public string GlyphFromMergedResource { get; set; }

    //pass page in constructor for referencing the page local resource dictionary
    public FontViewModel(Page page)
    {
        GlyphFromClass = Icons.Glyph;

        //ResourceDictionary applicationResourceDictionary = Application.Current.Resources;

        ResourceDictionary localResourceDictionary = page.Resources;

        string str = string.Empty;
        if (localResourceDictionary.TryGetValue("Glyph", out object obj) && obj is OnPlatform<string>)
        {
            str = (OnPlatform<string>)obj;
        }

        GlyphFromMergedResource = str;
    }
}

如有必要,为viewmodel类实现INotifyPropertyChanged并在属性中使用OnPropertyChanged

页面xaml代码后面的Viewmodel使用示例:

InitializeComponent();

BindingContext = new FontViewModel(this);

具有绑定的Xaml:

<Label Text="{Binding GlyphFromClass}" FontFamily="{StaticResource FontFamily}" />
<Label Text="{Binding GlyphFromMergedResource}" FontFamily="{StaticResource FontFamily}" />

具有静态资源的Xaml:

<Label Text="{x:Static i:Icons.Glyph}" FontFamily="{StaticResource FontFamily}" />
<Label Text="{StaticResource Glyph}" FontFamily="{StaticResource FontFamily}" />

答案 3 :(得分:0)

您可以使用数据触发器,

<Label Text="">
     <Label.Triggers>
        <DataTrigger TargetType="Label"
                  Binding="{Binding IconName}"
                  Value="Account">
                  <Setter Property="Text" Value="{StaticResource Account}"/>
         </DataTrigger>
     </Label.Triggers>
</Label>

您可以为每个要匹配的条件编写多个 DataTriggers 并设置 StaticResource