Wpf 如何构建翻译文本的绑定标记扩展?

Wpf 如何构建翻译文本的绑定标记扩展?,wpf,data-binding,binding,internationalization,Wpf,Data Binding,Binding,Internationalization,我正在用WPF重写Delphi7应用程序。一个要求是所有标签、标题、消息等都可以翻译成另一种语言。我需要使用现有的内部翻译引擎,而不是使用资源的.NET i18n 我非常希望扩展绑定标记扩展,以便能够指定结果字符串所使用的语言。这只适用于单向绑定,例如简单的{binding namelab Lang=Twi},因此名称字段的标签显示在Twi中 我相信我可以从binding对象继承,并重写某个方法以通过服务定位器}调用翻译服务,然后再传递从数据上下文请求的值。您可以从绑定中派生,但不能重写行为以更

我正在用WPF重写Delphi7应用程序。一个要求是所有标签、标题、消息等都可以翻译成另一种语言。我需要使用现有的内部翻译引擎,而不是使用资源的.NET i18n

我非常希望扩展绑定标记扩展,以便能够指定结果字符串所使用的语言。这只适用于单向绑定,例如简单的{binding namelab Lang=Twi},因此名称字段的标签显示在Twi中

我相信我可以从binding对象继承,并重写某个方法以通过服务定位器}调用翻译服务,然后再传递从数据上下文请求的值。

您可以从绑定中派生,但不能重写行为以更改返回值,也就是说,您不能截取中间的代码,因为ProvideValue方法标记为sealed inBindingBase类,这样您就不能重写它并在派生类中进行更改

BindingBase中的定义:

public override sealed object ProvideValue(IServiceProvider serviceProvider);
但是,如果您对将返回i18n字符串的自定义标记扩展感兴趣,可以这样做:

public class CustomBinding : MarkupExtension
{
    public string Lang { get; set; }

    public static object GetValue(DependencyObject obj)
    {
        return obj.GetValue(ValueProperty);
    }

    public static void SetValue(DependencyObject obj, Binding value)
    {
        obj.SetValue(ValueProperty, value);
    }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.RegisterAttached("Value", typeof(object), 
                                             typeof(CustomBinding));        


    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        IProvideValueTarget pvt = serviceProvider as IProvideValueTarget;
        DependencyObject targetObject = pvt.TargetObject as DependencyObject;

        if (targetObject == null)
        {
            return String.Empty;
        }

        string value = GetValue(targetObject).ToString();
        // You get the bound value here. Put i18n code here
        // and return actual value. (Access Lang property to get the culture)
        return value;
    }
}
正如您所看到的,我声明了附加属性而不是普通的DP,因为您必须从DependencyObject派生,但我们已经从MarkupExtension派生,因此无法执行多重继承。必须解决附加属性问题,以提供来自XAML的绑定支持

XAML中的用法:


当然,您必须在XAML中定义本地名称空间。

类似于?@user3411327的东西是的,这看起来很理想,但看起来也严重依赖于资源文件,我的雇主希望避免创建资源文件,而使用现有的字典代码。您可以插入自己的@user3411327,这看起来很棒,但是该接口的最新版本有一个未记录的GetFullyQualifiedResourceKey方法,只有NotImplementedException。除了name值(某些元素可能已经有了该值)之外,它看起来可以正常工作。我将附加LocalText或其他内容。谢谢
<TextBlock local:CustomBinding.Value="{Binding PropertyName}"
           Text="{local:CustomBinding Lang=Twi}"/>