简体   繁体   English

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

[英]Using an IValueConverter on non bound data in XAML

I have an IValueConverter that I wrote to handle localization and translation in WPF elements; 我编写了一个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();
    }
}

But I also want to use it in non bound data aswell, ie send a known string into the converter rather than a property from the elements data context. 但是我也想在非绑定数据中使用它,即将已知字符串发送到转换器中,而不是从元素数据上下文中发送属性。 How can I go about that? 我该怎么办?

Guess I should clarify, my intent is to use this in XAML for the UI and would be helpful if it had a design time support aswell. 猜猜我应该澄清一下,我的意图是在XAML中将其用于UI,如果它还具有设计时间支持,将很有帮助。

I did attempt a variation that used the ConverterParameter to feed the source string, but in design time all my text is replaced with System.Object text, so not very useful. 我确实尝试过使用ConverterParameter来输入源字符串的变体,但是在设计时,我的所有文本都被System.Object文本替换了,所以不是很有用。

Would also like if at all possible to avoid creating a overloaded or inherited user-control. 还要尽可能避免创建重载或继承的用户控件。

You could create a MarkupExtension that would take a string as a parameter and call your converter in the ProvideValue override. 您可以创建将string作为参数的MarkupExtension ,然后在ProvideValue覆盖中调用您的转换器。 Here's an example implementation: 这是一个示例实现:

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);
    }
}

Then you'd use it in XAML like this: 然后,您将在XAML中像这样使用它:

<TextBlock Text="{local:Translate 'text to translate'}" />

Note though that changing language will require the XAML to be re-read as the ProvideValue method is only called once upon realization of your XAML definition. 请注意,尽管更改语言将要求重新读取XAML,因为仅在实现XAML定义ProvideValue方法。 If you want a dynamic approach you could refer for example to this answer. 如果您希望采用动态方法,则可以参考答案。

But I also want to use it in non bound data aswell, ie send a known string into the converter rather than a property from the elements data context. 但是我也想在非绑定数据中使用它,即将已知字符串发送到转换器中,而不是从元素数据上下文中发送属性。 How can I go about that? 我该怎么办?

You can't really do this because the Convert method of a Converter will only be invoked when the binding to the source property is resolved and when the source property is updated. 您实际上无法做到这一点,因为仅在解析到source属性的绑定以及更新source属性时才调用Converter的Convert方法。 If the binding to the source property fails, for example when you have defined an invalid binding path in your XAML markup or when there simply is no DataContext to bind to, your Convert method won't be called. 如果与source属性的绑定失败,例如,当您在XAML标记中定义了无效的绑定路径时,或者根本没有要绑定的DataContext时,将不会调用Convert方法。

And when there is no binding applied to the target property at all, the converter won't be invoked either. 而且,如果根本没有将绑定应用于目标属性,则转换器也不会被调用。

So you will have to always make sure that there actually is a property to bind to for this to work. 因此,您必须始终确保确实存在要绑定的属性才能起作用。 Maybe you can bind to a dummy property or something. 也许您可以绑定到虚拟属性或其他东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM