简体   繁体   English

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

[英]How to change language at runtime without layout troubles

I have a winforms application that the users must be able to change the language at runtime. 我有一个winforms应用程序,用户必须能够在运行时更改语言。

To generalize the switch and avoid having to hard code control names I tried the following extension: 为了概括开关并避免硬编码控制名称,我尝试了以下扩展:

    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);
        }
    }

This does change all the strings. 这确实改变了所有字符串。

However a side effect of this is that the entire contents of the window is resized to that windows original startup size, no matter what the current size is. 然而,这样做的副作用是,无论当前大小如何,窗口的整个内容都会调整为该窗口的原始启动大小。

How can I prevent the layout from changing or initiate a new layout calculation? 如何防止布局更改或启动新的布局计算?

Look at the .resx file to see what all is getting reassigned. 查看.resx文件以查看所有重新分配的内容。 Properties like Size and Form.AutoScaleDimensions are localizable properties. Size和Form.AutoScaleDimensions等属性是可本地化的属性。 Reassigning them has the kind of effect you are seeing. 重新分配它们会产生你所看到的那种效果。 Especially undoing the auto-scaling would be quite unpleasant. 特别是撤消自动缩放将是非常不愉快的。

No specific advise to fix this problem, this just isn't made to be run in any other place than the form constructor. 没有具体的建议来解决这个问题,这不是在表单构造函数之外的任何其他地方运行。 Reconstruct the form. 重建表格。 Pointing out that the actual user of your form never feels a need to change her native language on-the-fly never seems to make an impression. 指出您的表单的实际用户从未觉得需要即时更改她的母语似乎永远不会给人留下印象。

This is the complete code I am using now. 这是我现在使用的完整代码。

The change is to manually change the Text property only. 更改是仅手动更改Text属性。 If I get to localize other properties, the code will have to be expanded afterwards. 如果我要本地化其他属性,则必须在之后扩展代码。

    /// <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;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM