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

时间:2014-03-21 17:10:46

标签: wpf data-binding binding internationalization

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

我非常希望扩展Binding标记扩展,以便能够指定结果字符串所在的语言。这只适用于单向绑定,例如一个简单的{"绑定NameLabel Lang = Twi"}所以Name字段的标签显示在Twi中。

我确信我可以从绑定对象继承,并在它从数据上下文传递请求的值之前,覆盖一些方法来调用翻译服务(通过Service Locator}。

1 个答案:

答案 0 :(得分:0)

您可以从Binding派生但您无法覆盖行为来更改返回值,即您无法拦截之间的代码,因为{{1} }方法在BindingBase类中被标记为密封,因此您无法覆盖它并在派生类中进行更改。

BindingBase中的定义:

ProvideValue

但是如果您对自定义标记扩展感兴趣,它将返回i18n字符串,您可以这样做:

public override sealed object ProvideValue(IServiceProvider serviceProvider);

正如您所看到的,我声明了附加属性而不是普通DP,因为您必须从DependencyObject派生,但我们已经从MarkupExtension派生,因此无法进行多重继承。必须与附属财产结算以提供XAML的绑定支持。

XAML中的用法:

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

当然,您必须在XAML中定义<TextBlock local:CustomBinding.Value="{Binding PropertyName}" Text="{local:CustomBinding Lang=Twi}"/> 命名空间。