我有一个XAML窗口,它有一组绑定到对象的字符串:
<Label Content="{StaticResource LabelUserName}" HorizontalAlignment="Right" Name="Label1" VerticalAlignment="Center" />
当我像这样定义我的ResouceDictionary时,这段代码工作正常:
<Window.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Strings/Strings_en-US.xaml" />
</ResourceDictionary.MergedDictionaries>
<ObjectDataProvider x:Key="objLogon" ObjectType="{x:Type StarUtilities:Logon}" />
</ResourceDictionary>
</Window.Resources>
但是,我希望能够更改绑定字符串的位置,因此我创建了一个如下所示的模块:
Public Module LocalizationChooser
Public ReadOnly Property GetLocalization As Uri
Get
Return New Uri("/Strings/Strings_en-US.xaml", UriKind.Relative)
End Get
End Property
End Module
然后我决定尝试将Source
更改为Binding字符串。但是,我尝试过以下操作,但没有工作:
<ResourceDictionary Source="{Binding Source={x:Static Member=StarUI:LocalizationChooser.GetLocalization}}" />
<ResourceDictionary Source="{x:Static Member=StarUI:LocalizationChooser.GetLocalization}" />
<ResourceDictionary Source="{Binding Source=StarUI:LocalizationChooser.GetLocalization}" />
<ResourceDictionary Source="{Binding Source=LocalizationChooser, Path=GetLocalization}" />
<ResourceDictionary Source="{Binding Source=StarUI:LocalizationChooser, Path=GetLocalization}" />
<ResourceDictionary Source="{Binding Source={x:Static Member=StarUI:LocalizationChooser.GetLocalization}, Path=GetLocalization}" />
<ResourceDictionary Source="{Binding Source={x:Static Member=StarUI:LocalizationChooser.GetLocalization}, Path=LocalizationChooser.GetLocalization}" />
<ResourceDictionary Source="{Binding Source={x:Static Member=StarUI:LocalizationChooser.GetLocalization}, Path=StarUI:LocalizationChooser.GetLocalization}" />
所有产生相同的错误:
在“ResourceDictionary”上抛出了ArgumentNullException:值不能为null 参数名称:item
我能做些什么才能让它发挥作用?
我应该提一下,StarUI名称空间已经定义如下:
xmlns:StarUI="clr-namespace:StarUI"
修改:
我发现,随着我对模块所做的更改,我可以使用以下代码编译和运行:
<ResourceDictionary Source="{x:Static StarUI:LocalizationChooser.GetLocalization}" />
但是,我仍然没有设计时支持。由于模块返回的静态项不需要查找任何内容,有没有办法在这里获得设计时支持?如果没有,有没有办法在XAML中指定设计时的静态引用,然后是运行时的动态引用?
编辑2 :
我最后做的是编写静态指定Source
的XAML,然后将构造函数设置为'覆盖'。由于将根据添加的最后一个引用具有相同名称的字典条目,我可以在运行时添加字典,但在设计时仍然有字典。
我使用以下内容简单地本地化我的代码,包括设计时支持和动态更改语言。
在我的XAML中,我包括:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="LocalizationStrings" Source="/Strings/Strings_en-US.xaml" />
</ResourceDictionary.MergedDictionaries>
<ObjectDataProvider x:Key="objLogon" ObjectType="{x:Type StarUtilities:Logon}" />
</ResourceDictionary>
</Window.Resources>
在我的代码隐藏中:
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.Resources.MergedDictionaries.Add(GetLocalization)
End Sub
GetLocation位于公共模块中:
Public ReadOnly Property GetLocalization As ResourceDictionary
Get
Dim resourceLocalization As New ResourceDictionary
resourceLocalization.Source = New Uri("/Strings/Strings_zh-cn.xaml", UriKind.Relative)
Return resourceLocalization
End Get
End Property
我的ResourceDictionary XAML样本是:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="ButtonLogon">Logon</sys:String>
<sys:String x:Key="ButtonCancel">Cancel</sys:String>
<sys:String x:Key="LabelUserName">User Name:</sys:String>
<sys:String x:Key="LabelPassword">Password:</sys:String>
<sys:String x:Key="LabelKey">Decryption Key:</sys:String>
</ResourceDictionary>
然后我只需通过以下方式访问语言字符串:
<Label Content="{DynamicResource LabelUserName}" Name="Label1" />
现在一切都很棒!
答案 0 :(得分:4)
您需要从StaticResource切换到DynamicResource,因为您的资源不能立即使用。
但是你不能在ResourceDictionary属性上使用Bindings,因为它不是从DependencyObject派生的。
答案 1 :(得分:0)
如果将本地化资源移动到单独的程序集,则仍可以在ResourceDictionary文件中使用静态资源。您需要添加&#34;程序集&#34; uri到你的标题ns引用(即:xmlns:loc="clr-namespace:MyDLL.Strings;assembly=MyDll.Localization"
)。
然后您可以像往常一样使用本地化资源而无需额外的代码:
<Label Content="{x:Static loc:LocalizationStrings.TitleXXX}" />
我总是在单独的程序集中使用我的本地化资源。