C# 在XAML中的非绑定数据上使用IValueConverter

C# 在XAML中的非绑定数据上使用IValueConverter,c#,wpf,ivalueconverter,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)

我有一个
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文本替换,因此不是很有用

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

但我也希望在非绑定数据中使用它,即将已知字符串发送到转换器,而不是元素数据上下文中的属性。我该怎么做呢

您无法真正做到这一点,因为只有在解析到源属性的绑定并更新源属性时,才会调用转换器的Convert方法。如果绑定到源属性失败,例如,当您在XAML标记中定义了无效的绑定路径,或者根本没有要绑定到的DataContext时,将不会调用Convert方法

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

因此,您必须始终确保实际上有一个属性要绑定才能使其工作。也许你可以绑定到一个虚拟属性或其他东西

但我也希望在非绑定数据中使用它,即将已知字符串发送到转换器,而不是元素数据上下文中的属性。我该怎么做呢

您无法真正做到这一点,因为只有在解析到源属性的绑定并更新源属性时,才会调用转换器的Convert方法。如果绑定到源属性失败,例如,当您在XAML标记中定义了无效的绑定路径,或者根本没有要绑定到的DataContext时,将不会调用Convert方法

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


因此,您必须始终确保实际上有一个属性要绑定才能使其工作。可能您可以绑定到一个伪属性或其他东西。

您可以创建一个
标记扩展名
,该扩展名将
字符串
作为参数,并在
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,因为只有在实现XAML定义时才会调用
ProvideValue
方法一次。如果您想要动态方法,您可以参考示例来回答。

您可以创建一个
标记扩展名
,该扩展名将
字符串
作为参数,并在
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,因为只有在实现XAML定义时才会调用
ProvideValue
方法一次。如果您需要动态方法,您可以参考示例来回答。

像调用任何其他函数一样简单地调用该函数。@AnjumSKhan据我所知,您不能在XAML中调用函数。@Wabbles您在问题中没有提到任何关于XAML的内容。请说得更具体些。尝试给出一个示例,说明您希望如何在绑定之外使用转换器。@Clemens我对其进行了编辑以澄清,但我确实说了“在WPF元素中进行翻译”@Clemens因此进行了澄清,我错误地认为,自从IVACONV实现以来,人们不需要说就得到了该部分。简单地像调用任何其他函数一样调用该函数。@AnjumSKhan据我所知,您不能在XAML中调用函数。@Wabbles您在问题中没有提到任何关于XAML的内容。请说得更具体些。试着给出一个示例,说明您希望如何在绑定之外使用转换器。@Clemens我编辑它是为了澄清,但我确实说了“WPF元素中的翻译”@Clemens因此澄清,我错误地认为人们从IValConv实现以来就不需要说就得到了该部分。虽然我怀疑这是正确的途径,我尝试这样做,然后将原始字符串通过
ConverterParameter
导致在设计时读取所有文本“System Object”。我想避免这种情况。我也不反对改变我的方法,也许你可以编写自己的自定义标记扩展来执行本地化,而不是使用转换器:你认为如何创建一个键控集合来扩展实现我的翻译的dictionary类,然后直接绑定到该类,并调用我的原始字符串作为键?可能不是标准做法,但如果它起作用,实现将像
{Vinding本地化:Store[My English phrase to convert]}
一样简单。希望这在设计时也能起作用。如果您通过控件的DataContext属性公开字典,这听起来是合理的。虽然我怀疑这是正确的轨迹,但我尝试这样做,然后通过
ConverterParameter
传递原始字符串,导致我的所有文本都读取“System Object”在设计时。我想避免这种情况。我也不反对改变我的方法,也许你可以编写自己的自定义标记扩展来执行本地化,而不是使用转换器:你认为如何创建一个键控集合来扩展实现我的翻译的dictionary类,然后直接绑定到该类,并调用我的原始字符串作为键?可能不是标准做法,但我