【问题标题】:Localization at runtime运行时本地化
【发布时间】:2012-10-26 13:12:41
【问题描述】:

我已经用 C# 创建了 Windows 窗体程序。 我在本地化方面遇到了一些问题。 我有 3 种语言的资源文件。 我想单击每个语言按钮并在运行时更改语言。 当我在InitializeComponent() 之前更改语言时,它可以工作。 但是当我点击按钮时,它不起作用。 我正在使用此代码。

private void RussianFlag_Click(object sender, EventArgs e)
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("ru-RU");
}

【问题讨论】:

  • 您是否也尝试过更改Thread.CurrentCulture
  • 在将线程文化设置为另一种语言后,您是否尝试过调用Refresh()
  • 我怀疑您是否需要 ComponentResourceManager 并可能通过循环所有控件来应用

标签: c# .net winforms localization


【解决方案1】:

我写了一个RuntimeLocalizer 类,具有以下特点:

  • 更改和更新表单中所有 Controls 和 SubControls 的本地化
  • 还更改了所有SubItems 和所有MenuStrips 的本地化

用法示例:RuntimeLocalizer.ChangeCulture(MainForm, "en-US");


using System.Windows.Forms;
using System.Globalization;
using System.Threading;
using System.ComponentModel;

public static class RuntimeLocalizer
{
    public static void ChangeCulture(Form frm, string cultureCode)
    {
        CultureInfo culture = CultureInfo.GetCultureInfo(cultureCode);

        Thread.CurrentThread.CurrentUICulture = culture;

        ComponentResourceManager resources = new ComponentResourceManager(frm.GetType());

        ApplyResourceToControl(resources, frm, culture);
        resources.ApplyResources(frm, "$this", culture);
    }

    private static void ApplyResourceToControl(ComponentResourceManager res, Control control, CultureInfo lang)
    {
        if (control.GetType() == typeof(MenuStrip))  // See if this is a menuStrip
        {
            MenuStrip strip = (MenuStrip)control;

            ApplyResourceToToolStripItemCollection(strip.Items, res, lang);
        }

        foreach (Control c in control.Controls) // Apply to all sub-controls
        {
            ApplyResourceToControl(res, c, lang);
            res.ApplyResources(c, c.Name, lang);
        }

        // Apply to self
        res.ApplyResources(control, control.Name, lang);
    }

    private static void ApplyResourceToToolStripItemCollection(ToolStripItemCollection col, ComponentResourceManager res, CultureInfo lang)
    {
        for (int i = 0; i < col.Count; i++)     // Apply to all sub items
        {
            ToolStripItem item = (ToolStripMenuItem)col[i];

            if (item.GetType() == typeof(ToolStripMenuItem))
            {
                ToolStripMenuItem menuitem = (ToolStripMenuItem)item;
                ApplyResourceToToolStripItemCollection(menuitem.DropDownItems, res, lang);
            }

            res.ApplyResources(item, item.Name, lang);
        }
    }
}

【讨论】:

  • 效果很好!谢谢!运行时本地化更改的最佳解决方案,非常容易实现!
  • 非常有帮助!谢谢!我尝试了很多方法,只有你的作品谢谢!
  • 我也用这个类。一件有趣的事情是它可能会改变控件的大小,因为维度也是“可本地化的”,并且它们的值存储在资源文件中。如果应用此类后表单变得“跳跃”,则从文件中删除不需要的维度值。
【解决方案2】:

您需要重新加载控件以反映新文化价值观

ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));

然后您必须使用resources.ApplyResources 申请每个控件

请有look here

【讨论】:

  • 虽然是一个很好的入门教程,但它打开了几个问题的大门
【解决方案3】:

更改 CurrentUICulture 不会自动重新加载资源。您需要手动执行 (http://msdn.microsoft.com/en-us/magazine/cc163609.aspx#S8)

您可以从 InitializeComponent() 复制与本地化相关的代码 进入另一个函数:

void LoadResources(){

    this.Title = MyApp.Resources.MainFormCaption;
    this.lblWelcomeMessage.Text = MyApp.Resources.UserWelcome;

}

【讨论】:

    【解决方案4】:

    感谢 V4Vendetta 和其他人。 解决办法是……

    private void RussianFlag_Click(object sender, EventArgs e)
            {
                if (currentLanguage != "RUS")
                {
                    Thread.CurrentThread.CurrentUICulture = new CultureInfo("ru-RU");
                    ChangeLanguage("ru-RU");
                }
            }
    

    .... …… ...

    private void ChangeLanguage(string lang)
            {
                foreach (Control c in this.Controls)
                {
                    ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
                    resources.ApplyResources(c, c.Name, new CultureInfo(lang));
                    if (c.ToString().StartsWith("System.Windows.Forms.GroupBox"))
                    {
                        foreach (Control child in c.Controls)
                        {
                            ComponentResourceManager resources_child = new ComponentResourceManager(typeof(Form1));
                            resources_child.ApplyResources(child, child.Name, new CultureInfo(lang));
                        }
                    }
                }
            }
    

    【讨论】:

    • 这里是递归解决方案: private void ChangeLanguage(Control ctl, string lang) { ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1)); resources.ApplyResources(ctl, ctl.Name, new CultureInfo(lang)); foreach (ctl.Controls 中的控制 c) ChangeLanguage(c, lang); }
    猜你喜欢
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2015-10-26
    相关资源
    最近更新 更多