Reputation: 5634
I have a scenario where my Xamarin Label displays an Icon from a ttf file. As it stands, the Label looks as follows.
<Label
Text="{StaticResource Account}"/>
Where Account is a string in my Styles.xaml file that defines the Hex value.
<x:String x:Key="Account"></x:String>
The above works just fine. However, I would like to bind the Icon text name via a property in my ViewModel. The following does not work, but I am thinking of something like this:
Text="{StaticResource Binding=IconName}"
How would I accomplish this?
UPDATE: adding some more context to this question.
In my Styles.xaml I am defining a dictionary that corresponds to their hex values
<x:String x:Key="Back"></x:String>
<x:String x:Key="Share"></x:String>
<x:String x:Key="Next"></x:String>
<x:String x:Key="Account"></x:String>
<x:String x:Key="Bell"></x:String>
<x:String x:Key="Mail"></x:String>
<x:String x:Key="Help"></x:String>
This styles file is a resource to my xaml file.
<ContentPage.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ContentPage.Resources>
In my XAML file, I am iterating through to display different icons.
<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>
And in my List, I am specifying the Icon name.
MenuItems = new List<AppMenuItem>()
{
new AppMenuItem()
{
Title = "View A",
IconSource = "Account",
},
new AppMenuItem()
{
Title = "View B",
IconSource = "Mail",
}
};
UPDATE 2: I am trying to build a value converter, but I can't seem to access the merged dictionaries. I am using:
Application.Current.Resources.TryGetValue(value.ToString(), out var retValue);
retValue is always returning NULL.
Upvotes: 2
Views: 2799
Reputation: 795
You can use data trigger,
<Label Text="">
<Label.Triggers>
<DataTrigger TargetType="Label"
Binding="{Binding IconName}"
Value="Account">
<Setter Property="Text" Value="{StaticResource Account}"/>
</DataTrigger>
</Label.Triggers>
</Label>
You can write multiple DataTriggers for each condition you want to match and set StaticResource
Upvotes: 1
Reputation: 2985
Define class for icon glyphs:
namespace MyNamespace
{
public static class Icons
{
public const string Glyph = "\ue000";
...
}
}
Resource dictionary /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>
Reference resource dictionary from page:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Glyphs.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
ViewModel example:
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;
}
}
If needed, implement INotifyPropertyChanged
for viewmodel class and use OnPropertyChanged
in properties.
Viewmodel usage example in page xaml code behind:
InitializeComponent();
BindingContext = new FontViewModel(this);
Xaml with binding:
<Label Text="{Binding GlyphFromClass}" FontFamily="{StaticResource FontFamily}" />
<Label Text="{Binding GlyphFromMergedResource}" FontFamily="{StaticResource FontFamily}" />
Xaml with static resources:
<Label Text="{x:Static i:Icons.Glyph}" FontFamily="{StaticResource FontFamily}" />
<Label Text="{StaticResource Glyph}" FontFamily="{StaticResource FontFamily}" />
Upvotes: 0
Reputation: 96
-----:::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"></x:String>
<x:String x:Key="Share"></x:String>
<x:String x:Key="Next"></x:String>
<x:String x:Key="Account"></x:String>
<x:String x:Key="Bell"></x:String>
<x:String x:Key="Mail"></x:String>
<x:String x:Key="Help"></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"];
}
}
}
Upvotes: 0
Reputation: 72
you can bind to a style of the label.
<Style TargetType="Label">
<Setter Property="Text" Value="{Binding Account}"/>
</Style>
Upvotes: 0