【问题标题】:How can I build a Binding Markup Extension that translates text?如何构建翻译文本的绑定标记扩展?
【发布时间】:2014-03-21 17:10:46
【问题描述】:

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

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

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

【问题讨论】:

  • 类似this?
  • @user3411327 是的,这看起来很理想,但看起来也严重依赖资源文件,我的雇主希望避免创建这些资源文件以支持他们现有的字典代码。
  • 你可以自己插上localization provider
  • @user3411327 看起来不错,但该接口的最新版本有一个未记录的GetFullyQualifiedResourceKey 方法,只有NotImplementedException
  • 看到这个answer

标签: wpf data-binding binding internationalization


【解决方案1】:

你可以从Binding派生,但是你不能覆盖行为来改变返回的值,即你不能截取中间的代码因为ProvideValue方法被标记了在 BindingBase 类中密封,因此您不能覆盖它并在派生类中进行更改。

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 中的用法:

<TextBlock local:CustomBinding.Value="{Binding PropertyName}"
           Text="{local:CustomBinding Lang=Twi}"/>

当然你必须在 XAML 中定义 local 命名空间。

【讨论】:

  • 我试试看。看起来它可以正常工作,除了名称Value,某些元素可能已经有。我会附上LocalText 或其他东西。谢谢。
猜你喜欢
  • 2016-07-09
  • 2021-07-04
  • 1970-01-01
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多