在XAML中对非绑定数据使用IValueConverter

时间:2017-01-22 11:48:40

标签: c# wpf ivalueconverter

我写了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文本,因此不太有用。

还希望尽可能避免创建重载或继承的用户控件。

2 个答案:

答案 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方法。

当根本没有对目标属性应用绑定时,也不会调用转换器。

因此,您必须始终确保实际存在要绑定的属性才能使其正常工作。也许你可以绑定到虚拟财产或其他东西。