【问题标题】:WPF: How to change the CurrentUICulture at runtimeWPF:如何在运行时更改 CurrentUICulture
【发布时间】:2011-01-07 14:43:58
【问题描述】:

我正在尝试更改我的 WPF 应用在单击事件中使用的语言,但它没有改变。

private void menuItemGerman_Click(object sender, RoutedEventArgs e)
{
   Settings.Default.Culture = "de-DE";

   Thread.CurrentThread.CurrentCulture = new CultureInfo(Settings.Default.Culture);
   Thread.CurrentThread.CurrentUICulture = new CultureInfo(Settings.Default.Culture);
}

我错过了什么?

【问题讨论】:

  • 改变文化不会自动翻译你的 UI 文本。它确实做了很多事情,但并非如此。您是否提供过任何德语文本翻译?

标签: c# .net wpf vb.net


【解决方案1】:

我错过了什么?

您更改了在线程中注册的文化,String.Format 现在将使用它,但您需要重新加载 WPF 层次结构中的所有本地化项。

WPF Localization – On-the-fly Language Selection 有更多信息。

【讨论】:

【解决方案2】:

如果你有资源文件,例如:

  • Resources.resx
  • Resources.hu-hu.resx

...并想在运行时更改本地化,

...并且不想弄乱额外的资源字典和重新编码所有 UI 本地化,

它适用于

Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);

但是它不会改变已经显示的窗口的语言。

要实现这一点,需要更多编码 - 必须管理应用程序生命周期,而不是默认的。

首先,从 App.xaml 中删除 StartupUri:

<Application
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         x:Class="ADUI.App"
         xmlns:System="clr-namespace:System;assembly=mscorlib" >
     <!--StartupUri="wndMain.xaml">-->
<Application.Resources>
</Application.Resources>

其次,实现一个类,它现在负责应用程序的生命周期:

public class LocApp: Application
{
    [STAThread]
    public static void Main()
    {
        App app = new App();
        app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
        wndMain wnd = new wndMain();
        wnd.Closed += Wnd_Closed;
        app.Run(wnd);
    }

    private static void Wnd_Closed(object sender, EventArgs e)
    {
        wndMain wnd = sender as wndMain;
        if (!string.IsNullOrEmpty(wnd.LangSwitch))
        {
            string lang = wnd.LangSwitch;

            wnd.Closed -= Wnd_Closed;

            Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);

            wnd = new wndMain();
            wnd.Closed += Wnd_Closed;
            wnd.Show();
        }
        else
        {
            App.Current.Shutdown();
        }
    }
}

不要忘记将项目属性/应用程序页面上的启动对象更改为 LocApp!

最后,在主窗口的代码中实现一些切换语言的代码:

public partial class wndMain : Window
{
    public string LangSwitch { get; private set; } = null;

    // ... blah, blah, blah

    private void tbEn_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        LangSwitch = "en";
        Close();
    }

    private void tbHu_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        LangSwitch = "hu-hu";
        Close();
    }

    // ... blah, blah, blah

}

确保提供的本地化代码与 resx 文件语言代码之一匹配(本例中为“hu-hu”)!

此解决方案将使用所选语言关闭并重新打开主窗口,如果主窗口以其他方式关闭,则会退出。

【讨论】:

    【解决方案3】:

    我也遇到过这个问题,我的解决方法是:

    • Resources.zh-CN
    • Resources.pt-PT

    我创建了一个类,它将返回带有键和标签的字典:

    public class Labels : ObservableObject
    {
        public Dictionary<string, string> Items { get; set; }
        public string this[string name]
        {
            get
            {
                return Items.ContainsKey(name) ? Items[name] : "";
            }
        }
    
        public Labels()
        {
            Items = new Dictionary<string, string>();
        }
    }
    

    接下来,还有一个类来获取资源:

    public static class LanguageUtils
    {
        public static Labels GetLangLables(string label)
        {
            var resources = Resources.ResourceManager.GetResourceSet(new CultureInfo(label), true, true);
            return new Labels
            {
                Items = resources.Cast<DictionaryEntry>().ToDictionary(r => r.Key.ToString(), r => r.Value.ToString())
            };
        }
    }
    

    当您需要某种语言时:

    LanguageUtils.GetLangLables("pt-PT");
    

    曾经,你不能提升 (RaisePropertyChanged()) 静态属性,使用这个:

    public class LanguageContext
    {
        private static LanguageContext _languageContext;
        public static LanguageContext Instance
        {
            get
            {
                if (_languageContext == null)
                {
                    _languageContext = new LanguageContext();
                }
    
                return _languageContext;
            }
        }
    
        protected LanguageContext()
        {
            CurrentLangLabels = LanguageUtils.GetLangLables("en-US");
         }
         public Labels CurrentLangLabels { get; set; }
    }
    

    现在您可以更新语言了:

    LanguageContext.Instance.CurrentLangLabels = LanguageUtils.GetLangLables(SelectedLanguage.Resource);
    

    这样加注:

    public Labels CurrentLangLabels
    {
       get { return LanguageContext.Instance.CurrentLangLabels; }
       set { RaisePropertyChanged(); }
    }
    

    并使用标签:

    CurrentLangLabels.Items[LabelName]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      • 2011-08-14
      • 2017-12-31
      • 1970-01-01
      相关资源
      最近更新 更多