本地化绑定

3
我正在解决一个本地化问题。这不是普通的语言本地化。
<Label Content="{Binding myDictionary[A Test], FallbackValue=A Test}"/>

实际上,上述代码调用了视图模型中声明为字典的内容。
public Dictionary<string, string> myDictionary

问题在于我必须在标签中两次定义字符串“A Test”。 一次是在绑定的索引中,另一次是在FallbackValue中。
我想最终得到的结果看起来像这样...
<Label Content="{Binding myDictionary[A Test]}"/>

目前我这样做的结果是,在 Visual Studio 的 Xaml 设计器中无法解析 myDictionary(因为它不知道数据上下文,所以无法连接到定义它的视图模型),这意味着标签将显示为空白,这将使可视化设计更加困难。
我已经尝试调用静态方法,但是为了使 myDictionary 正常工作,它需要在视图模型中实例化。
有没有一种方法可以在设计器中显示索引值“A Test”,而不必使用备用值?
目标是能够在更新 myDictionary[A Test] 中的值时刷新内容(实际上,myDictionary 是可观察的)。

你可能想要查看WPF本地化扩展项目。即使您不直接使用它(有钩子从任何数据源获取本地化值),通过标记扩展实现可能是更好的选择。 - Mike Zboray
2个回答

1

我认为处理这个问题的最佳方式是使用自定义标记扩展,放置在自定义命名空间中,它允许你编写以下类似XAML的代码:

<TextBlock Text="{Translate 'Hello World!'} />
< p>Translate扩展类返回的内容完全由您决定,通常您可以使用提供的字符串作为索引在字典中进行查找,如果没有找到,则返回字符串本身。

这个特定实现的一个好处是它为每个绑定添加了一个监听器,因此当当前语言更改时,它们都会自动更新运行时。

但是,您必须记住的一件事是将Translate扩展类本身放置在其自己的项目中。不确定为什么,似乎这是VS中的一个错误,但是XAML文件似乎无法使用在同一项目中声明的自定义标记扩展。


1
作为它不知道数据上下文,因此无法连接到定义它的视图模型。
不是这样的...可以通过在页面的元数据属性中指定仅限设计时间的上下文来使用。
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d:DataContext="{d:DesignInstance {x:Type viewModels:MainVM}}"

通过这样做,您可以设置一个仅在设计时使用的字典。

在MSDN杂志上阅读相关内容:

MVVM - 最大化设计时数据对可视化设计师的使用

请注意,在非Blend编辑器(如Visual Studio)中仍然可以使用Blend命名空间。否则,根据需要使用/学习Blend即可。


如果从您的实际虚拟机中使用真实数据,在设计模式下忽略某些可能会导致问题的对象/操作是很好的。这里有一个检查,用于确定该操作是否处于设计模式,如果不是,则执行该块,否则将被忽略,因为它处于设计模式。
if (!DesignerProperties.GetIsInDesignMode(this))

@ColinDawson Blend编辑器还有一些模拟数据的方法,而Visual Studio没有。 - ΩmegaMan
DesignerProperties.GetIsInDesignMode对我没有任何帮助,因为我需要从我的视图模型中调用它。当然,我的视图模型无法在正确的上下文中获取“this”。 - Colin Dawson
我觉得我的解决问题的整个方法都不对。可能需要重新开始。 - Colin Dawson
我想要做的是本地化应用程序,但不想像微软那样使用资源文件,而是想使用数据库,并且能够动态更新字符串。我的意思是,如果更改了本地化查找表,字符串可以在你眼前实时更改。 - Colin Dawson
一直在思考和寻找替代方案。我认为使用标记扩展找到了一个可行的解决方案。这将让我从数据上下文中提取字典,并且如果字典不可用,也允许文本可见。 - Colin Dawson
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接