我正在重写WPF中的Delphi 7应用程序。一个要求是所有标签,标题,消息等都可以翻译成另一种语言。我需要使用现有的内部翻译引擎,而不是使用资源的.NET i18n。
我非常希望扩展Binding
标记扩展,以便能够指定结果字符串所在的语言。这只适用于单向绑定,例如一个简单的{"绑定NameLabel Lang = Twi"}所以Name字段的标签显示在Twi中。
我确信我可以从绑定对象继承,并在它从数据上下文传递请求的值之前,覆盖一些方法来调用翻译服务(通过Service Locator}。
答案 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}"/>
命名空间。