3

.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」であると仮定すると、どのようにこれを行うことができますか: 「A」である「fileToolStripMenuItem1.Text」の値を fileToolStripMenuItem1.Text に割り当てる

4

1 に答える 1

0

私はいくつかのテスト用の 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 
于 2012-06-21T15:36:49.183 に答える