如何在运行时更改语言而不会出现布局问题

hul*_*ist 10 c# localization runtime winforms

我有一个winforms应用程序,用户必须能够在运行时更改语言.

为了概括开关并避免硬编码控制名称,我尝试了以下扩展:

    internal static void SetLanguage(this Form form, CultureInfo lang)
    {
        ComponentResourceManager resources = new ComponentResourceManager(form.GetType());

        ApplyResourceToControl(resources, form, lang);
        resources.ApplyResources(form, "$this", lang);
    }

    private static void ApplyResourceToControl(ComponentResourceManager resources, Control control, CultureInfo lang)
    {
        foreach (Control c in control.Controls)
        {
            ApplyResourceToControl(resources, c, lang);
            resources.ApplyResources(c, c.Name, lang);
        }
    }
Run Code Online (Sandbox Code Playgroud)

这确实改变了所有字符串.

然而,这样做的副作用是,无论当前大小如何,窗口的整个内容都会调整为该窗口的原始启动大小.

如何防止布局更改或启动新的布局计算?

Han*_*ant 5

查看.resx文件以查看所有重新分配的内容.Size和Form.AutoScaleDimensions等属性是可本地化的属性.重新分配它们会产生你所看到的那种效果.特别是撤消自动缩放将是非常不愉快的.

没有具体的建议来解决这个问题,这不是在表单构造函数之外的任何其他地方运行.重建表格.指出您的表单的实际用户从未觉得需要即时更改她的母语似乎永远不会给人留下印象.


hul*_*ist 5

这是我现在使用的完整代码.

更改是仅手动更改Text属性.如果我要本地化其他属性,则必须在之后扩展代码.

    /// <summary>
    /// Change language at runtime in the specified form
    /// </summary>
    internal static void SetLanguage(this Form form, CultureInfo lang)
    {
        //Set the language in the application
        System.Threading.Thread.CurrentThread.CurrentUICulture = lang;

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

        ApplyResourceToControl(resources, form.MainMenuStrip, lang);
        ApplyResourceToControl(resources, form, lang);

        //resources.ApplyResources(form, "$this", lang);
        form.Text = resources.GetString("$this.Text", lang);
    }

    private static void ApplyResourceToControl(ComponentResourceManager resources, Control control, CultureInfo lang)
    {
        foreach (Control c in control.Controls)
        {
            ApplyResourceToControl(resources, c, lang);
            //resources.ApplyResources(c, c.Name, lang);
            string text = resources.GetString(c.Name+".Text", lang);
            if (text != null)
                c.Text = text;
        }
    }

    private static void ApplyResourceToControl(ComponentResourceManager resources, MenuStrip menu, CultureInfo lang)
    {
        foreach (ToolStripItem m in menu.Items)
        {
            //resources.ApplyResources(m, m.Name, lang);
            string text = resources.GetString(m.Name + ".Text", lang);
            if (text != null)
                m.Text = text;
        }
    }
Run Code Online (Sandbox Code Playgroud)