【发布时间】:2021-12-09 13:43:03
【问题描述】:
我正在尝试为 WPF 创建一个用于翻译的 MarkupExtension。我在这里发现了一些类似的问题,包括
MarkupExtension that uses a DataBinding value
How do I resolve the value of a databinding inside a MarkupExtension?
最终,这导致了看起来很有希望的response by Torvin。但是,作为cmets中的一个人,我有一个问题,target.GetValue()获取的值总是返回null。
这是一些代码。
最终我有一组静态类,其中包含一个静态 KeyDefinition 对象,如下所示
Public class KeyDefinition
{
Public string Key {get; set;}
Public string DefaultValue {get; set;}
}
键与 JSON 资源相关联,而 DefaultValue 是英文翻译,我们可以将其用于 xaml 的设计时显示。
本地化是通过像Localize.GetResource(key)这样的静态类进行的
我的目标是像这样编写 XAML
<TextBlock Text="{Localize {Binding KeyDefinitionFromDataContext}}">
其中KeyDefinitionFromDataContext 是视图模型中的一个属性,它返回对KeyDefinition 对象的引用。
根据 Torvin 的回复,我创建了一个这样的 MarkupExtension
public class LocalizeExtension : MarkupExtension
{
private readonly BindingBase _binding;
private static readonly DependencyProperty _valueProperty = DependencyProperty.RegisterAttached("Value", typeof(KeyDefinition), typeof(LocalizeExtension));
[ConstructorArgument("keyDefinition")
public KeyDefinition KeyDefinition {get; set;}
public LocalizeExtension(Binding binding)
{
_binding = binding;
}
public LocalizeExtension(KeyDefinition keyDefinition)
{
KeyDefinition = keyDefinition;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var pvt = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
var target = pvt.TargetObject as DependencyObject;
var property = pvt.TargetProperty as DependencyProperty;
//If inside a template, WPF will call again when its applied
if (target == null)
return this;
BindingOperations.SetBinding(target, property, _binding);
KeyDefinition = (KeyDefinition)target.GetValue(_valueProperty);
BindingOperations.ClearBinding(target, property);
return Localize.GetResource(KeyDefinition.Key);
}
}
现在请原谅我,因为我通常不做 WPF 的工作,但是这个任务已经落到了我的身上。每当我运行这段代码时,返回的值总是Null。我试过直接使用字符串而不是“KeyDefinition”对象,但遇到了同样的问题。
我认为这里让我感到困惑的是目标上的 DependencyProperty 是如何设置的,因为它是私有的。
感谢任何帮助。谢谢!
【问题讨论】:
-
您的 LocalizeExtension 类甚至不会编译,至少当 KeyDefinition 是静态类时不会。静态类不能用作属性类型或构造函数参数。
-
您还必须在 SetBinding、GetValue 和 ClearBinding 调用中使用
_valueProperty字段,而不是本地的property变量(这样就没有用了)。但即使进行了这种修改,这种方法也行不通。它看起来像是偶然发生的事情,您不应该尝试这样做。使用另一种方法并附加一个绑定转换器。 -
最终目标是本地化吗?我通常通过使用每种语言的资源字典来做到这一点,其中包含所有字符串。以所需的任何语言进行合并,并将动态资源与视图中的键一起使用。在法语中合并,它的键与视图中使用的原始英语键匹配,您会看到法语。
-
对不起。我写这个问题的时候有一个错字。 KeyDefinition 类不应该是静态的。那已经更新了。我同意你的看法,我认为克莱门斯。我真的不明白这将如何运作。我将尝试另一种方法。
-
理想情况下,我只需回答其他威胁中的问题并要求澄清,但我没有足够的代表这样做。
标签: c# wpf xaml localization