c# - 应用程序在运行时更改语言

标签 c# winforms reflection multilingual

我已经阅读了有关如何在 .Net 中制作多语言程序的教程,它运行良好,但在这里我需要一个想法来使运行时的所有事情变得更容易。 在运行时,当用户单击该语言时。我将文化更改为选择的适当语言,例如:

Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");    

然后调用一个函数来为我的表单布局设置文本:

private System.Resources.ResourceManager rm;
fileToolStripMenuItem1.Text =  rm.GetString("fileToolStripMenuItem1.Text");
settingsToolStripMenuItem.Text = rm.GetString("settingsToolStripMenuItem.Text");

当我为我的程序的每个组件设置文本时,.Net 构建的查找表似乎等于应该设置到其中的属性。换句话说,“fileToolStripMenuItem1.Text”正在传递给 GetString() 函数,结果应设置为 fileToolStripMenuItem1.Text,所以我不知道该怎么做,甚至不知道可以使用哪种工具进行迭代在 rm 的每个属性上,然后通过反射或其他方式将键的值分配给键。也就是说,假设“fileToolStripMenuItem1.Text”是查找表中的键,值为“A”,那么我该怎么做:将“fileToolStripMenuItem1.Text”的值“A”分配给 fileToolStripMenuItem1.Text

最佳答案

我已经编写了一些测试 winforms 应用程序并进行了尝试,并且可以很好地动态更改控件的 Text 属性。如果需要,您可以扩展此解决方案。

    using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ConsoleApplication5
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

    //main logic of switching language of UI
    void ChangeCulture_Handler(CultureInfo culture)
    {
        //getting relative path of resource file for specific culture
        var resourcePath = GetLocalizedResourceFile(culture);
        //initialize new reader of resource file
        var reader = new ResXResourceReader(resourcePath);
        //getting enumerator
        var resourceEnumerator = reader.GetEnumerator();
        //enumerate each record in resource file
        while (resourceEnumerator.MoveNext())
        {
            string resKey = Convert.ToString(resourceEnumerator.Key);
            //we can add here some check if need 
            //(for example if in resource file exists not only controls resources with format <Control Name>.<Property>
            //if( resKey.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Length == 2) 
            string resValue = Convert.ToString(resourceEnumerator.Value);
            //actually update property
            UpdateControl(resKey, resValue);
        }
    }

    //main logic of updating property of one control
    private void UpdateControl(string resKey, string resValue)
    {
        //we suppose that format of keys in resource file is <Control Name>.<Property>
        var strs = resKey.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
        var controlName = strs[0];
        var controlProp = strs[1];

        //find control of form by its name
        var controls = this.Controls.Find(controlName, true);
        if (controls.Length > 0)
        {
            //select first control
            var control = controls[0];
            //getting type of it
            var t = control.GetType();
            //getting property
            var props = t.GetProperty(controlProp);
            if (props != null)
            {
                //setting localized value to property
                props.SetValue(control, resValue, null);
            }
        }
    }

    //build resource file path
    string GetLocalizedResourceFile(CultureInfo ci)
    {
        string cultureCode = ci.TwoLetterISOLanguageName;
        //for english language is default, so we don't have a need to add "en" part in path 
        return cultureCode != "en" ? string.Format("Resource1.{0}.resx", cultureCode) : "Resource1.resx";
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Thread.CurrentThread.CurrentCulture = new CultureInfo("es-MX");
        ChangeCulture_Handler(Thread.CurrentThread.CurrentCulture);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
        ChangeCulture_Handler(Thread.CurrentThread.CurrentCulture);
    }
}

英文资源(Resource1.resx)

button1.Text    Change language to es   
button2.Text    Change language to en   
label1.Text         label1  
label2.Text         label2  

西类牙语资源 (Resource1.es.resx)

button1.Text    cambiar el idioma to es 
button2.Text    cambiar el idioma to en 
label1.Text     lalble1 
label2.Text     lalble2 

关于c# - 应用程序在运行时更改语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11097211/

相关文章:

c# - 具有 System.Windows.Forms 和自定义基类的自定义 WinForms 控件

c# - ListView 项添加事件

.net - Image.FromFile 非常非常慢

java - 无法通过反射设置 boolean 值

C# - 获取调用方法的程序集?

c# - Chrome 83 中取消的 HTTP 请求

c# - 如何在 C# 中创建可以粘贴到 Excel 中的结构

c# - 使用反射循环类变量

c# - 将查询字符串作为参数传递给 Asp.net MVC 时遇到问题

c# - 在 C# 应用程序中模仿 SQL Server Profiler?