动态本地化WPF应用程序与资源文件

Cap*_*iSo 6 c# wpf localization

为了使我的wpf appliaction本地化,我遵循了这个CodeProject教程.

我创建了我的本地化资源文件(例如,Resource.resx,Resource.en-US.resx)并将它们绑定在xaml中的label元素上

<Label Foreground="{StaticResource ApplicationForgroundColor}" FontSize="21"
           Content="{x:Static strings:Resources.title}"/> 
Run Code Online (Sandbox Code Playgroud)

在LocalizedService中,我设置了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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Content="{DynamicResource strings:Resources.title}"
Run Code Online (Sandbox Code Playgroud)

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

小智 5

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

您开始实现BindingExtenstion:

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

然后,您需要实现和之间的连接ResourceManager,将CultureInfo其实现为单例以启用同步访问。它定义了绑定元素的Source,并且在本地化更改时触发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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,本地化的资源文件(例如Resource.resx,Resource.en-US.resx)位于文件夹中,<Project>/Resources/Strings/Resources/否则您需要更新此部分代码。

现在,您可以使用以下新绑定:

<Label Foreground="{StaticResource ApplicationForgroundColor}" FontSize="21"
       Content="{util:Localization title}"/>
Run Code Online (Sandbox Code Playgroud)

要在运行时更改语言环境,您需要设置:

public static void SetLanguage(string locale)
{
    if (string.IsNullOrEmpty(locale)) locale = "en-US";
    TranslationSource.Instance.CurrentCulture = new System.Globalization.CultureInfo(locale);
}
Run Code Online (Sandbox Code Playgroud)