如何更改表单中所有控件的文本语言

时间:2014-09-18 07:40:35

标签: c# winforms

有没有办法在运行时更改表单中所有控件的语言?

例如,我在表单中有一个按钮,它的文本为“Hello”。如何在运行时将其更改为不同的语言?动态地我可以设置的每种语言。有办法吗?

我找到了答案,但似乎它不起作用与cultureinfo有关。有什么建议吗?

这是我的代码

public partial class Form1 : BaseLanguageForm
    {
        public Form1()
        {
            InitializeComponent();   
        }



        private void button1_Click(object sender, EventArgs e)
        {
            this.TriggerLanguageChange("fr-FR");
        }
    }
 public class LanguageArgs : EventArgs
    {
        string _languageSymbol;
        /// <summary>
        /// Gets the language symble.
        /// </summary>
        public string LanguageSymbol
        {
            get { return _languageSymbol; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="LanguageArgs"/> class.
        /// </summary>
        /// <param name="symbol">The symbol.</param>
        public LanguageArgs(string symbol)
        {
            this._languageSymbol = symbol;
        }
    }
    public class BaseLanguageForm : Form
    {
        /// <summary>
        /// Triggers the language change event.
        /// </summary>
        /// <param name="languageSymbol">The language symbol.</param>
        protected void TriggerLanguageChange(string languageSymbol)
        {
            if (Form1.onLanguageChanged != null)
            {
                LanguageArgs args = new LanguageArgs(languageSymbol);
                Form1.onLanguageChanged(this, args);
            }
        }

        /// <summary>
        /// This should be triggered whenever the combo box value chages
        /// It is protected, just incase you want to do any thing else specific to form instacne type
        /// </summary>
        protected static event EventHandler<LanguageArgs> onLanguageChanged;

        /// <summary>
        /// This will be called from your form's constuctor 
        /// (you don't need to do anything, the base class constuctor is called automatically)
        /// </summary>
        public BaseLanguageForm()
        {
            //registering to the event
            BaseLanguageForm.onLanguageChanged += new EventHandler<LanguageArgs>(BaseLanguageForm_onLanguageChanged);
        }

        /// <summary>
        /// The function that was regidtered to the event
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The e.</param>
        void BaseLanguageForm_onLanguageChanged(object sender, LanguageArgs e)
        {
            string lang = e.LanguageSymbol;
            foreach (Control c in this.Controls)
            {
                ComponentResourceManager crm = new ComponentResourceManager(typeof(Form1));
                crm.ApplyResources(c, c.Name, new CultureInfo(lang));
            }
        }

    }

1 个答案:

答案 0 :(得分:3)

您必须翻译两种内容:表单上可见的控件和运行时所需的字符串,更改按钮的Text或MessageBox的标题等。

您可以在设计器中翻译表单上的控件:

  • 首先完成Laguage = Standard中的所有布局。
  • 然后将属性选项卡中的“语言”更改为其他语言。
  • 现在翻译所有控件中的所有文本。
  • 您可能还需要稍微更改布局以允许更长的文本;这很好!

查看项目资源管理器:对于每个表单和每种语言,现在都有一个新的FormN.lang.resx文件,例如:

Form1.resx
Form1.en.resx
Form1.de.resx

现在当你调用changeLanguage函数时,可能就像这样:

private void ChangeLanguage(Control ctl, string lang)
{
   resources.ApplyResources(ctl, ctl.Name, new CultureInfo(lang));
   foreach (Control c in ctl.Controls) ChangeLanguage(c, lang);
}

也许是这样的:

private void cb_language_Click(object sender, EventArgs e)
{
    if (cb_language.Text == "DE")
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");
        resources = new ComponentResourceManager(typeof(Form1));
        ChangeLanguage(this, "de-DE");
        cb_language.Text = "EN";
    }
    else
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
        resources = new ComponentResourceManager(typeof(Form1));
        ChangeLanguage(this, "en-US");
        cb_language.Text = "DE";
    }
}

..所有可见的控件都会更改其文本。

要做的第二件事是创建字符串资源文件,最好用于标准每种语言一个(重复标准值!):Add new element - resource file,其名称如下: / p>

strings.resx
strings.de.resx
strings.en.resx

然后为代码中需要的每个字符串添加一个名称 - 值对,例如:

msgCap_OW           File Exists
msgTxt_OW           Overwrite (Yes)
                    Use next free Index? (No)
                    Cancel?
cb_autoScrapeStart  Start Timed Screenshots

注意:通过在值字段中输入 - 输入,您可以输入多行值..

最后,您必须更改代码才能使用字符串资源,例如:像这样:

MessageBox.Show(strings.msgTxt_OW, strings.msgCap_OW, ..);

或:

cb_autoScrape.Text = (scrapeTimer.Enabled ? 
                      strings.cb_autoScrapeStop : strings.cb_autoScrapeStart);