使用BoolToObjectConverter搭配TranslateExtension未返回翻译字符串
在XAML中使用Xamarin Community Toolkit(XCT)的BoolToObjectConverter,将TrueObject和FalseObject属性通过TranslateExtension绑定到可翻译字符串:
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}}" />
预期Label显示翻译后的“是”或“否”,但实际输出为:
Xamarin.Forms.Binding
尝试添加x:TypeArguments="BindingBase"无效,且不想用DataTrigger避免代码冗余,希望继续使用BoolToObjectConverter解决问题。
问题根源在于TranslateExtension在绑定上下文环境中返回的是Binding对象,而非直接的翻译字符串,BoolToObjectConverter会直接将这个Binding对象返回给Label,导致Label显示其类型名称而非解析后的值。以下是两种可行的解决方式:
方式一:自定义转换器直接获取翻译值
创建一个继承自IValueConverter的自定义转换器,直接通过XCT的TranslationManager获取翻译后的字符串:
using System; using System.Globalization; using Xamarin.CommunityToolkit.Extensions; using Xamarin.Forms; namespace YourNamespace { public class BoolToTranslatedStringConverter : IValueConverter { // 对应True状态的翻译键 public string TrueTranslationKey { get; set; } // 对应False状态的翻译键 public string FalseTranslationKey { get; set; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is bool boolValue) { var key = boolValue ? TrueTranslationKey : FalseTranslationKey; return TranslationManager.Instance.Translate(key); } return string.Empty; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }
在XAML中引用并使用该转换器:
xmlns:local="clr-namespace:YourNamespace" ... <local:BoolToTranslatedStringConverter x:Key="BoolToAnswerConverter" TrueTranslationKey="YesAnswer" FalseTranslationKey="NoAnswer" /> ... <Label Text="{Binding Foo, Converter={StaticResource BoolToAnswerConverter}}" />
方式二:通过资源定义翻译值再绑定
如果你的本地化资源是通过RESX文件管理的,可以直接将TrueObject和FalseObject绑定到RESX资源的属性,这样能直接获取到翻译后的字符串:
假设你的RESX资源类名为AppResources,则XAML代码如下:
xmlns:res="clr-namespace:YourApp.Resources" ... <xct:BoolToObjectConverter x:Key="Converter" TrueObject="{x:Static res:AppResources.YesAnswer}" FalseObject="{x:Static res:AppResources.NoAnswer}" /> ... <Label Text="{Binding Foo, Converter={StaticResource Converter}}" />
这种方式无需自定义转换器,直接利用静态资源获取翻译值,避免了TranslateExtension返回Binding对象的问题。
内容的提问来源于stack exchange,提问作者Anders Gustafsson

