xamarin.formstranslationivalueconverterxamarin-community-toolkit

Using BoolToObjectConverter with TranslateExtension True/FalseObject does not return translated string


I am using the BoolToObjectConverter from Xamarin Community Toolkit (XCT) in my XAML file. The TrueObject and FalseObject properties are set to translatable strings where I use the TranslateExtension from XCT:

xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
...
<xct:BoolToObjectConverter x:Key="Converter" TrueObject="{xct:Translate YesAnswer}" FalseObject="{xct:Translate NoAnswer}" />
...
<Label Text="{Binding Foo, Converter={StaticResource Converter}}" />

I would have expected that the Label text would have been the translated yes or no answer.

Unfortunately the actual Label output is

Xamarin.Forms.Binding

The issue could be solved by not using a converter but instead using a DataTrigger to set the Label.Text depending on the value of Foo. However, this clutters the XAML code; I would like to stick to using the BoolToObjectConverter. What can I do to obtain the translated string output instead of just the Binding type?

EDIT
Alternatively, I could add x:TypeArguments="BindingBase" in the converter definition, since this is the return type of the TranslateExtension.ProvideValue method, but this does not make any difference to the output result.


Solution

  • The best solution I could come up with was to subclass XCT TranslateExtension and implement IMarkupExtension for a string return value. This way I could use the subclass to obtain translated strings in the converter.

    Implementation

    public class TranslateToStringExtension : Xamarin.CommunityToolkit.Extensions.TranslateExtension, IMarkupExtension<string>
    {
        public new string ProvideValue(IServiceProvider serviceProvider)
        {
            var binding = base.ProvideValue(serviceProvider) as Binding;
            string path;
            var value = string.IsNullOrEmpty(path = binding?.Path?.Trim('[', ']'))
                ? null
                : LocalizationResourceManager.Current.GetValue(path);
            return value;
        }
    }
    

    Usage

    <xct:BoolToObjectConverter 
      x:Key="Converter" 
      TrueObject="{local:TranslateToString YesAnswer}" 
      FalseObject="{local:TranslateToString NoAnswer}" />