在运行时更改语言的正确方法

for*_*atc 22 c# globalization localization winforms

在运行时更改Form语言的正确方法是什么?

  1. 设置使用递归喜欢手动控制所有
  2. 将语言选择保存到文件>重新启动应用程序>加载语言选择之前 InitializeComponent();
  3. 使用Form构造函数替换active的实例(如果这是可能的话)
  4. 还有别的

关于这一点有很多一半的书面线程,但没有一个提供真正的答案,正确的方法是什么?

更新:
澄清我的问题:

做这样的事情:

public Form1()
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("de");
    this.InitializeComponent();
}
Run Code Online (Sandbox Code Playgroud)

工作正常,我的所有控件和资源中的其他所有内容都可以正确翻译.做一些像:

private void button1_Click(object sender, EventArgs e)
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("en");
}
Run Code Online (Sandbox Code Playgroud)

什么都不做,表格保持我以前设置的语言 InitializeComponent();

mnn*_*mnn 23

我相信Hans Passant评论中显示的解决方案可能是唯一的(通用)解决方案.

就个人而言,我将这个基类用于需要本地化的所有表单:

public class LocalizedForm : Form
{
    /// <summary>
    /// Occurs when current UI culture is changed
    /// </summary>
    [Browsable(true)]
    [Description("Occurs when current UI culture is changed")]
    [EditorBrowsable(EditorBrowsableState.Advanced)]
    [Category("Property Changed")]
    public event EventHandler CultureChanged;

    protected CultureInfo culture;
    protected ComponentResourceManager resManager;

    /// <summary>
    /// Current culture of this form
    /// </summary>
    [Browsable(false)]
    [Description("Current culture of this form")]
    [EditorBrowsable(EditorBrowsableState.Never)]
    public CultureInfo Culture
    {
        get { return this.culture; }
        set
        {
            if (this.culture != value)
            {
                this.ApplyResources(this, value);

                this.culture = value;
                this.OnCultureChanged();
            }
        }
    }

    public LocalizedForm()
    {
        this.resManager = new ComponentResourceManager(this.GetType());
        this.culture = CultureInfo.CurrentUICulture;
    }

    private void ApplyResources(Control parent, CultureInfo culture)
    {
        this.resManager.ApplyResources(parent, parent.Name, culture);

        foreach (Control ctl in parent.Controls)
        {
            this.ApplyResources(ctl, culture);
        }
    }

    protected void OnCultureChanged()
    {
        var temp = this.CultureChanged;
        if (temp != null)
            temp(this, EventArgs.Empty);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我不是直接更改Thread.CurrentThread.CurrentUICulture,而是在静态管理器类中使用此属性来更改UI文化:

public static CultureInfo GlobalUICulture
{
    get { return Thread.CurrentThread.CurrentUICulture; }
    set
    {
        if (GlobalUICulture.Equals(value) == false)
        {
            foreach (var form in Application.OpenForms.OfType<LocalizedForm>())
            {
                form.Culture = value;
            }

            Thread.CurrentThread.CurrentUICulture = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果仅循环"parent.Controls",则不会遍历控制树.例如,TabControl将其tabPages保存在"parent.TabPages"中.MenuStrip的项目位于"parent.Items"中.等等. (15认同)

小智 5

我发现了另一种方法:

如下所示在私有方法中移动初始化表单代码

private void FormInitialize() {/*Your code here*/}
Run Code Online (Sandbox Code Playgroud)

在表单构造函数中像这样使用它

public Form1()
{
    InitializeComponent();
    FormInitialize();
}
Run Code Online (Sandbox Code Playgroud)

然后从Button,menuItem或其他调用方法

private void ChangeCultureToFrench_Click(object sender, EventArgs e)
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr");
    this.Controls.Clear();
    this.InitializeComponent();
    FormInitialize();
}
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助 ;-)