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

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

    }

最佳答案

您必须翻译两种内容:表单上可见的控件以及您在运行时需要的字符串,以更改按钮的文本或消息框的标题等。

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

  • 首先在 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";
    }
}

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

要做的第二件事是创建字符串资源文件,最好为标准创建一个,为每种语言创建一个(重复标准值!):添加新元素 - 资源文件 的名称如下:

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

注意:通过在值字段中按 Shift 键输入,您可以输入多行值。

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

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

或者:

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

关于c# - 如何更改表单中所有控件上的文本语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25906909/

相关文章:

c# - C# 中的 "extension methods"是什么意思?

c# - 如何创建 'Private' ResourceDictionary?

c# - 是否应该通过组合或其他方式引入新行为?

c# - 如何将字典绑定(bind)到 MSChart

c# - 将字符串解析为 int 数组

c# - 无法对 Pen 进行更改,因为权限无效

winforms - 我可以更改配置文件中的 Web 服务引用 URL 吗?

c# - 如果文件存在则覆盖(c#、winform、批处理文件)

c# - 当我在 C# 中单击另一个按钮时,如何调用按钮单击事件

c# - 安全地比较本地和通用日期时间