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

发布于 2024-09-15 10:40:37 字数 802 浏览 6 评论 0原文

我有一个 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);
        }
    }

这确实更改了所有字符串。

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

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

I have a winforms application that the users must be able to change the language at runtime.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

停滞 2024-09-22 10:40:37

查看 .resx 文件以了解所有内容都被重新分配。 Size 和 Form.AutoScaleDimensions 等属性是可本地化的属性。重新分配它们会产生您所看到的效果。尤其是取消自动缩放会非常令人不快。

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

Look at the .resx file to see what all is getting reassigned. Properties like Size and Form.AutoScaleDimensions are localizable properties. 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.

长安忆 2024-09-22 10:40:37

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

更改只是手动更改 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;
        }
    }

This is the complete code I am using now.

The change is to manually change the Text property only. 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;
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文