我写了IValueConverter
来处理WPF元素中的本地化和翻译;
public class LanguageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return string.Empty;
if (value is string)
return LocalizedStrings.Retreive((string)value);
else
return string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
但我也想在非绑定数据中使用它,即将已知字符串发送到转换器而不是元素数据上下文中的属性。我怎么能这样做呢?
猜猜我应该澄清一下,我的意图是在XAML中使用它来获取UI,如果它还有设计时支持,那将会很有帮助。
我确实尝试过使用ConverterParameter
来提供源字符串的变体,但在设计时我的所有文本都替换为System.Object文本,因此不太有用。
还希望尽可能避免创建重载或继承的用户控件。
答案 0 :(得分:2)
您可以创建MarkupExtension
,将string
作为参数,并在ProvideValue
覆盖中调用转换器。这是一个示例实现:
public class TranslateExtension : MarkupExtension
{
public TranslateExtension(string text)
{
Text = text;
}
private static readonly LanguageConverter _converter = new LanguageConverter();
public string Text { get; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return _converter.Convert(Text, null, null, null);
}
}
然后你会在XAML中使用它:
<TextBlock Text="{local:Translate 'text to translate'}" />
请注意,虽然更改语言将需要重新读取XAML,因为ProvideValue
方法仅在实现XAML定义时调用一次。如果您想要一种动态方法,可以参考例如this回答。
答案 1 :(得分:0)
但我也想在非绑定数据中使用它,即将已知字符串发送到转换器而不是元素数据上下文中的属性。我怎么能这样做呢?
您无法真正执行此操作,因为只有在解析了对source属性的绑定以及更新source属性时才会调用Converter的Convert方法。如果对source属性的绑定失败,例如,当您在XAML标记中定义了无效的绑定路径或者没有要绑定的DataContext时,将不会调用Convert方法。
当根本没有对目标属性应用绑定时,也不会调用转换器。
因此,您必须始终确保实际存在要绑定的属性才能使其正常工作。也许你可以绑定到虚拟财产或其他东西。