Автоматический перевод форм


Я хочу, чтобы мои приложения для поддержки нескольких пользовательского интерфейса-языки (как i18n ака). Для этого я создал статический класс ниже, чтобы автоматически перевести бланк и все его содержимое на нужный язык. Он заглядывает в файл ресурсов для языка и региональных параметров пользователя, и заменяет .Текст свойства элементов управления со строками, которые он находит там, или падает-возвращается к исходной строки, который является английский.

Использование зовет TranslateForm(это) из каждого вида конструктора.

Два вопроса про мой код:
* Перегрузку "переводить" методом. Я не нашел способ преодолеть это.
* Специальная обработка различных элементов управления, которая кажется ненужной.

Я не профессиональный программист, поэтому любые исправления / улучшения / исправить мой код более чем приветствуется!

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

namespace blahblah
{
    static class TranslationHelper
    {
        static private ResourceManager rm = null;

        static private CultureInfo default_ci = null;

        static private CultureInfo lang_ci = null;

        /// <summary>
        /// translate control into the specific lang, or leave it untranslated if no translation string found
        /// </summary>
        /// <param name="ctrl"></param>
        /// <param name="lang"></param>
        static private void Translate(Control ctrl, string lang)
        {
            string str = TranslateString(ctrl.Name, lang);
            if (str != null)
                ctrl.Text = str;
        }

        static private void Translate(ToolStripMenuItem o, string lang)
        {
            string str = TranslateString(o.Name, lang);
            if (str != null)
                o.Text = str;
        }

        static private void Translate(ToolStripItem o, string lang)
        {
            string str = TranslateString(o.Name, lang);
            if (str != null)
                o.Text = str;
        }

        static private void Translate(Form o, string lang)
        {
            string str = TranslateString(o.Name, lang);
            if (str != null)
                o.Text = str;
        }

        /// <summary>
        /// returns the <c>name</c> string from the <c>lang</c> resource
        /// </summary>
        /// <param name="name">string/key name</param>
        /// <param name="lang">the language to translate to</param>
        /// <returns>a translated string for <c>name</c></returns>
        static public string TranslateString(string name, string lang)
        {
            if (lang_ci == null || !lang_ci.TwoLetterISOLanguageName.Equals(lang))
                lang_ci = new CultureInfo(lang);

            try
            {
                return rm.GetString(name, lang_ci);
            }
            catch (Exception)
            {
                // no translation yet
                try
                {
                    return rm.GetString(name, default_ci);
                }
                catch (Exception)
                {
                    return null;
                    //MessageBox.Show(ex.Message.ToString(), name);
                    //System.Console.WriteLine(ex.Message.ToString());
                }
            }
        }

        static public void TranslateForm(string lang, Form parent)
        {
            if (rm == null)
                rm = new ResourceManager("etimet.i18nResources.i18n", Assembly.GetExecutingAssembly(), null);
            if (default_ci == null)
                default_ci = new CultureInfo("en");

            // handle direction
            if (Program.conf.CurrentLang.Equals("he") || Program.conf.CurrentLang.Equals("ar") || Program.conf.CurrentLang.Equals("fa"))
            {
                parent.RightToLeft = RightToLeft.Yes;
            }
            else
            {
                parent.RightToLeft = RightToLeft.No;
            }

            // translate the form itself
            Translate(parent, lang);

            // translate all the children controls, recursively
            Control.ControlCollection c = parent.Controls;
            foreach (Control o in c)
            {
                // special handling for the menu
                if (o.GetType() == typeof(MenuStrip))
                {
                    foreach (ToolStripMenuItem it in ((MenuStrip)o).Items)
                    {
                        Translate(it, lang);
                        //MessageBox.Show(it.Text);
                        foreach (ToolStripItem f in it.DropDownItems)
                        {
                            if (typeof(ToolStripSeparator) != f.GetType())
                                Translate(f, lang);
                        }
                    }
                }
                RecursiveTranslateCtrl(lang, o);
            }
        }

        static private void RecursiveTranslateCtrl(string lang, Control ctrl)
        {
            Translate(ctrl, lang);

            foreach (Control c in ctrl.Controls)
            {
                RecursiveTranslateCtrl(lang, c);
            }
        }
    }
}


3592
7
задан 10 февраля 2011 в 11:02 Источник Поделиться
Комментарии
2 ответа

Есть встроенные механизмы для автоматического переключения всей форме на использование текста культуры-конкретные файлы ресурсов, и он является более мощным, чем просто установка свойства text (например, подсказки). Единственный раз, вы должны вручную загрузить из файла ресурсов для таких вещей, как окна сообщений, но если вам нужно приложение для заблокировать при отображении уведомления вы могли бы также использовать подсказки, которые можно локализовать, а также. Это легкое место, чтобы начать. Он также будет более эффективным, так как элементы сами по себе являются локализация известны, так что нет необходимости в цикле ничего.

4
ответ дан 11 февраля 2011 в 02:02 Источник Поделиться

Вы можете избежать перегрузки с помощью общего суперкласса на ToolStripItem:

static private void Translate(ToolStripItem o, string lang)
{
string str = TranslateString(o.Name, lang);
if (str != null)
c.Text = str;
}

К сожалению, это работает только для этих двух компонент виды так как, похоже, компонент не имеет имени и текстовых атрибутов.

1
ответ дан 10 февраля 2011 в 07:02 Источник Поделиться