Как изменить язык во время выполнения без проблем с макетом - PullRequest
10 голосов
/ 24 августа 2010

У меня есть приложение 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);
        }
    }

Это меняет все строки.

Однако побочным эффектом этого является то, что все содержимое окна изменяется до исходного размера запуска Windows, независимо от текущего размера.

Как я могу предотвратить изменение макета или инициировать новый расчет макета?

Ответы [ 2 ]

5 голосов
/ 26 августа 2010

Это полный код, который я сейчас использую.

Изменение заключается в том, чтобы вручную изменять только свойство 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;
        }
    }
5 голосов
/ 24 августа 2010

Посмотрите на файл .resx, чтобы увидеть, что все переназначается. Такие свойства, как Size и Form.AutoScaleDimensions являются локализуемыми свойствами. Переназначение их имеет тот эффект, который вы видите. Особенно отмена автоматического масштабирования будет весьма неприятной.

Никаких конкретных советов по устранению этой проблемы нет, просто она не предназначена для запуска в каком-либо другом месте, кроме конструктора форм. Восстановить форму. Указание на то, что фактический пользователь вашей формы никогда не чувствует необходимости менять свой родной язык на лету, никогда не производит впечатление.

...