这里还有一种方法是由 Code Infinity 提出的,也使用了一个包装器来动态绑定资源文件。在这种方法中,INotifyPropertyChanged
事件会通知您的 UI 元素当地区发生变化时新的绑定资源文件。
您可以开始实现 BindingExtenstion:
public class LocalizationExtension : Binding
{
public LocalizationExtension(string name) : base("[" + name + "]")
{
this.Mode = BindingMode.OneWay;
this.Source = TranslationSource.Instance;
}
}
然后您需要实现ResourceManager
和CultureInfo
之间的连接,后者作为单例实现以启用同步访问。它定义了绑定元素的源,并在本地化更改时触发INotifyPropertyChanged
事件:
public class TranslationSource : INotifyPropertyChanged
{
private static readonly TranslationSource instance = new TranslationSource();
public static TranslationSource Instance
{
get { return instance; }
}
private readonly ResourceManager resManager = Resources.Strings.Resources.ResourceManager;
private CultureInfo currentCulture = null;
public string this[string key]
{
get { return this.resManager.GetString(key, this.currentCulture); }
}
public CultureInfo CurrentCulture
{
get { return this.currentCulture; }
set
{
if (this.currentCulture != value)
{
this.currentCulture = value;
var @event = this.PropertyChanged;
if (@event != null)
{
@event.Invoke(this, new PropertyChangedEventArgs(string.Empty));
}
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
请注意,您的本地化资源文件(例如Resource.resx、Resource.en-US.resx)在文件夹<Project>/Resources/Strings/Resources/
中,否则您需要更新此代码部分。
现在您可以使用这个新绑定:
<Label Foreground="{StaticResource ApplicationForgroundColor}" FontSize="21"
Content="{util:Localization title}"/>
在运行时更改语言环境,您需要设置:
public static void SetLanguage(string locale)
{
if (string.IsNullOrEmpty(locale)) locale = "en-US";
TranslationSource.Instance.CurrentCulture = new System.Globalization.CultureInfo(locale);
}
LocalizationExtension
实现在MyTool.Util
命名空间中,因此相应的xaml ns表达式看起来像:xmlns:util="clr-namespace:MyTool.Util"
。 - DTeuchertSetLanguage("en-IN")
。在这里重要的是避免打字错误,因此我定义了一个默认的语言代码(“en-US”)。请检查您的资源文件是否命名为:“Resources.en-IN.resx”。 - DTeuchert