具有资源文件的动态本地化 WPF 应用程序



为了使我的 wpf 应用程序本地化,我遵循了这个代码项目教程。

我创建了本地化的资源文件(例如,Resource.resx,Resource.en-US.resx(,并将其绑定到xaml中的标签元素上

<Label Foreground="{StaticResource ApplicationForgroundColor}" FontSize="21"
Content="{x:Static strings:Resources.title}"/> 

在本地化服务中,我设置了一些变更事件的CultureInfo

class LocalizationService
{
public static void SetLanguage(string locale)
{
if (string.IsNullOrEmpty(locale)) locale = "en-US";
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(locale);
}
}

此解决方案编译并显示正确的资源值,但由于静态绑定,我无法在运行时更改区域设置。 当我将内容绑定更改为如下所示的DynamicResource时,没有显示资源值。

Content="{DynamicResource strings:Resources.title}"

如何将文本值绑定到本地化的资源文件并在运行时动态更改它?

这里还有另一种 Code Infinity 的方法,它也使用包装器对资源文件进行动态绑定。 在这里,INotifyPropertyChanged事件会在区域设置更改时通知 UI 元素新的绑定资源文件。

您开始实现绑定扩展:

public class LocalizationExtension : Binding
{
public LocalizationExtension(string name) : base("[" + name + "]")
{
this.Mode = BindingMode.OneWay;
this.Source = TranslationSource.Instance;
}
}

然后,您需要实现ResourceManagerCultureInfo之间的连接,该连接作为单例实现,以启用同步访问。它定义了绑定元素的源,并在本地化更改时触发 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);
}

最新更新