Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use converters in Xamarin.Forms to convert text to color?

I want to have fixed enumeration of my app colors, i.e color for text, color for separators, and color for backgrounds, I don't want to type the same color every time I use it, so I thought that I may pass the object name (separator for example), and in the converter I convert it to the desired color: here's my implementation of the IValueConverter class:

class AppColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string)
        {
            var color = (string)value;
            switch (color)
            {
                case "separator":
                    return Color.FromHex("c2bca8");
                case "text":
                    return Color.FromHex("96907e");
                default:
                    return Color.Default;
            }
        }
        else
            return null;

    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

But I used this from my knowledge with data binding, but I simply want to pass a string to the color property, and the converter handle it , I added a ResourceDictionary:

  <Controls:CustomPage.Resources>
        <ResourceDictionary>
            <Converters:AppColorConverter x:Key="colorConverter"/>
        </ResourceDictionary>
    </Controls:CustomPage.Resources>

But how I use it , this doesn't work:

<Label Text="English" 
       VerticalOptions="CenterAndExpand" 
       HorizontalOptions="EndAndExpand" 
       TextColor="{separator, Converter=colorConverter}"/>
like image 798
mshwf Avatar asked Nov 02 '17 11:11

mshwf


3 Answers

You can also store your color values in a ResourceDictionary, like this:

<Color x:Key="ThemeBlue">#2499CE</Color>

Then in your switch statement, use this syntax:

return Application.Current.Resources["ThemeBlue"];

That way you can reuse your color values across all of the converters on your site, and manage them in a single place, your ResourceDictionary.

EDIT

You can bind as you are attempting, but you need to update your syntax. Try this:

<Label Text="English" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" TextColor="{Binding ., Converter={StaticResource colorConverter}, ConverterParameter='separator'}" />

And in your value converter, use the parameter object instead of the value object - we are passing "separator" as the parameter in this example. However, I wouldn't recommend this approach.

if (parameter is string)
        {
            var color = (string)parameter;
            ... etc ...

I think Diego's idea of just using a style is the way to go, but this answers your question and works in my test.

like image 92
David Conlisk Avatar answered Nov 17 '22 21:11

David Conlisk


It's just a detail you've forgoten: the static resource declaration to use the converter.

Here is how you must set the use of the converter:

<Label Text="English" 
       VerticalOptions="CenterAndExpand" 
       HorizontalOptions="EndAndExpand" 
       TextColor="{separator, Converter={StaticResource colorConverter}}"/>

Despite this, in your scenario, won't you think that a style it's a better approach?

like image 23
Diego Rafael Souza Avatar answered Nov 17 '22 22:11

Diego Rafael Souza


Basically you can't use that syntax {separator, Converter=colorConverter}, because curly braces indicate that you are using a markup extension (in this case it would mean that there is a separatorExtension somewhere in your codebase that inherits from MarkupExtension, and it has a property named Converter, but this won't work either because UWP doesn't support custom markup extensions). In case you tried to use the Binding markup extension(with its Converter, it should be something like this {Binding separator, C....), you can't do that either because it'll try to search for a 'separator' property in the DataContext of the containing element (but in WPF, you could bind to a static property, so you could create instances of your strings somewhere in your XAML and statically bind to it to use through the converter. We can't achieve this either in UWP). So your only option is to go with the resources approach as in David's answer and reference them via the {StaticResource MyColor} syntax.

like image 2
babgev Avatar answered Nov 17 '22 22:11

babgev