65.9K
CodeProject 正在变化。 阅读更多。
Home

如何翻译您的窗体应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.22/5 (9投票s)

2010年4月3日

Ms-PL

3分钟阅读

viewsIcon

41419

downloadIcon

576

轻松地将您的窗体应用程序翻译成多种语言。

引言

将您的应用程序翻译成多种语言可能非常困难。幸运的是,使用这段代码,您只需在文本文件中编写每个句子的翻译版本即可。

小提示:请原谅我提供给您的是 Visual Studio 2010 解决方案,您可以通过在记事本中打开它并将 2010 更改为 2008 来修改它。 它会运行良好。

工作原理

当您调用 Translate("此处填写语言") 方法时,应用程序会检查所选语言是否存在。 所谓的“存在”,是指“Languages”文件夹中是否包含任何带有翻译的文本文件。 如果该语言存在,它将打开该文本文件,读取数据并开始翻译。 如果不存在,它将创建该文本文件。

该文本文件将包含窗体上所有控件的文本,后跟一个等号。 等号前面的是原始文本,后面的是翻译后的单词。 在等号后写入翻译,然后再次调用 Translate() 方法。 您会看到控件的文本将被更改。

Using the Code

代码有很好的注释,但您仍然需要了解执行顺序。

我从编写构造函数开始

public Translator(Form toTranslate, string defaultLanguage)
{
    //Initializing variables
    mainForm = toTranslate;
    Default = defaultLanguage;
    CurrentLanguage = defaultLanguage;
            
    //Creating languages directory if it does not exist
    if (!Directory.Exists("Languages"))
    {
        Directory.CreateDirectory("Languages");
    }

    //We translate to the default language
    Translate(Default);
}

当我们初始化翻译器时,我们将不得不将我们要翻译的表单和我们的默认语言作为参数传递。

我们将翻译成默认语言,因为如果这是我们第一次调用该方法,则默认语言文件不存在。 当从一种语言翻译成另一种语言时,我们将使用具有默认语言的语言文件作为参考点。 假设我从法语翻译成日语,我需要先翻译成默认语言,然后再翻译成日语。 因此,我们将拥有一个包含默认语言的文件,该文件将在等号的左侧和右侧包含相同的单词。

接下来,我们将使用的变量

//These variables hold the values 
//of the form we want to translate, the default 
//language, and the current language
Form mainForm;
string Default;
string CurrentLanguage;

//This is used in the words array
struct wordsList
{
    public string Original, Translated;
};

wordsList struct 用于更容易地使用 Words[] 数组。

其余的代码像这样工作

Translate() 方法中,我们检查当前语言是否为默认语言。 如果不是,我们会将其翻译成默认语言。 如果是,那么我们检查我们选择的语言是否存在。 如果存在,我们打开带有翻译的文本文件,并将行加载到 Words[] 数组中

//Reading data from text file
StreamReader langIn = File.OpenText("Languages\\" + Language);
//While not end of file, we read the lines
//in the Words array
while (!langIn.EndOfStream)

{
string Line = langIn.ReadLine();
Words[number] = new wordsList();
Words[number].Original = Line.Substring(0, Line.LastIndexOf("="));
Words[number].Translated = Line.Substring(Line.LastIndexOf("=") + 1);
number++;
}

langIn.Close();

当我们向其中添加项目时,我们会增加 Words 数组的大小。 文本文件中等号左侧的单词是原始单词,右侧的是翻译版本。

加载单词后,我们循环遍历表单上的每个控件,并检查是否有任何单词与控件的文本匹配。 如果匹配,我们将文本更改为翻译后的版本

foreach (Control control in mainForm.Controls)
{
//We loop through all the controls
//and the words array, and if any of the 
//controls has the text property 
//to match the orginal word in the array,
//we replace it with the translated version
for (int i = 0; i <= number; i++)
{
if (control.Text == Words[i].Original)
{
control.Text = Words[i].Translated;
break;
}
}
}

最后,我们检查表单上是否有任何新单词。 我们循环遍历控件并检查是否有任何单词与该控件的文本匹配。 如果没有单词与控件的文本匹配,我们将其添加到 Words[] 数组中。

稍后,我们用所有的单词数组重写文本文件。 这样,如果语言文件最初不存在,我们会创建它

bool newWords = false;
foreach (Control control in mainForm.Controls)
{
//We assume it's new
bool ok = true;
for (int i = 0; i <= number; i++)
{
//If the word exists or it is empty "", we skip it
if (control.Text == Words[i].Original || control.Text == "")
ok = false;
}
//If it's a new word, we add it to the array
if (ok)
{
newWords = true;
Words[number] = new wordsList();
Words[number].Original = control.Text;
Words[number].Translated = "";
number++;
}
}
//We save the new words if any
if (newWords)
{
StreamWriter langOut = new StreamWriter("Languages\\" + Language);
for (int i = 0; i <= number; i++)
{
langOut.WriteLine(Words[i].Original + "=" + Words[i].Translated);
}
langOut.Close();
}

虽然所有这些可能会翻译我们的控件,但如果我们有一个消息框要显示,MessageBox.Show("Hello World"); 它将不会被翻译。 以下代码可用于翻译源代码中的任何 string

public string tr(string toTranslate)
        {
            wordsList[] Words = new wordsList[1000];
            int number = 0; //Counter for Words[]
            Words[number] = new wordsList();

            //Checking if language exists
            if (File.Exists("Languages\\" + CurrentLanguage))
            {
                #region Reading
                //Reading data from text file
                StreamReader langIn = File.OpenText("Languages\\" + CurrentLanguage);
                //While not end of file, we read the lines
                //in the Words array
                while (!langIn.EndOfStream)
                {
                    string Line = langIn.ReadLine();
                    Words[number] = new wordsList();
                    Words[number].Original = Line.Substring(0, Line.LastIndexOf("="));
                    Words[number].Translated = 
			Line.Substring(Line.LastIndexOf("=") + 1);
                    number++;
                }
                langIn.Close();
                #endregion
                #region Translating
                for (int i = 0; i <= number; i++)
                {
                    if (toTranslate== Words[i].Original)
                    {
                        return Words[i].Translated;
                    }
                }
                #endregion
                #region Adding to translation file                    
                StreamWriter langOut = new StreamWriter
				("Languages\\" + CurrentLanguage);
                for (int i = 0; i <= number; i++)
                {
                    langOut.WriteLine(Words[i].Original + "=" + Words[i].Translated);
                }
                langOut.WriteLine(toTranslate + "=");
                langOut.Close();
                #endregion
            }

            return toTranslate;
        } 

使用方法:

MessageBox.Show(translator.tr("Hello World"));

它会自动将其翻译成当前语言。

未实现的内容

当前代码不会翻译菜单或上下文菜单。 我计划在编写菜单代码后完成本文。

另外,您不能添加包含等号的单词或句子,因为这些单词将被错误地读取

string Line = langIn.ReadLine();
Words[number] = new wordsList();
Words[number].Original = Line.Substring(0, Line.LastIndexOf("="));
Words[number].Translated = Line.Substring(Line.LastIndexOf("=") + 1);
number++; 

我希望你喜欢这篇文章,更多内容即将推出。

历史

  • 4 月 8 日/10 - 增加了翻译源代码中 string 的可能性。
    MessageBox.Show(translator.tr("Hello World")); 
© . All rights reserved.